Rails Mysql: 如何只包含满足我条件的has_many关系对象?

Rails Mysql: How to only include has_many relation object that meet my condition?

我有以下 类:

    class User < ActiveRecord::Base
      has_many :keys
    end

    class Key < ActiveRecord::Base
      belongs_to :room
    end

    class Room < ActiveRecord::Base
      #has column "surface_area"
    end

我想查询拥有房间 surface_area 为 10 的钥匙的所有用户,仅包括房间表面积为 10 的钥匙。

我有以下查询:

User.joins(keys: :room).where('room.surface_area= ?', 10)

这 returns 用户拥有 room.surface_area 为 10 的钥匙,但它包括所有钥匙,因此也包括具有与 10 不同的表面积的空间的钥匙。我只想return 具有表面积为 10 的房间的键的子集。

错误的 return 值:

Users:{
 keys: [
  {id: 1, surface_area: 11},
  {id: 2, surface_area: 10},
  {id: 3, surface_area: 10}
 ]
}

正确的 return 值:

  Users:{
     keys: [
      {id: 2, surface_area: 10},
      {id: 3, surface_area: 10}
     ]
    }

json.rabl 用户文件

collection @users, :root => :users, :object_root => false

child :keys do
  extends "keys"
end
User.joins(keys: :room).where('room.surface_area= ?', 10)

此命令查询拥有表面积 = 10 房间钥匙的用户和 returns 用户。这是正确的。但是,当您对这些用户之一调用 keys 时,您将获得他们拥有的所有密钥。这也是正确的,因为这就是 has_many :keys 协会所做的。

你需要在User模型中定义一个新的实例方法,像这样:

def keys_for_rooms_with_surface_area(area)
  keys.joins(:room).where('rooms.surface_area = ?', area)
end

如果您希望has_many :keys总是return 表面积= 10 的房间的钥匙,您可以这样做:

has_many :keys, ->() { joins(:room).where('rooms.surface_area = 10') }

在这种情况下,您的第一个查询将如下所示:

User.joins(keys: :room)

为什么不尝试...

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :keys do
      def surface_area surface_area
         joins(:room).where(room: { surface_area: surface_area })
      end
   end
end

这应该使您能够调用:

@user = User.find params[:id]
@user.keys.surface_area 10

不行我就删,暗戳戳