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

时间:2015-12-28 11:58:17

标签: mysql ruby-on-rails has-many belongs-to

我有以下课程:

    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)

这将返回具有room.surface_area为10的键的用户,但它包含所有键,因此还有具有不同表面区域的空间的键。我只想返回具有不同表面区域的键的子集。表面积为10的房间。

错误的返回值:

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

正确的返回值:

  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

2 个答案:

答案 0 :(得分:1)

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

此命令查询用户并返回具有表面积为10的房间键的用户。这是正确的。但是,当您在其中一个用户上拨打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始终返回表面积为10的房间的密钥,您可以这样做:

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

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

User.joins(keys: :room)

答案 1 :(得分:0)

为什么不试试......

#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

如果它不起作用我会删除,只是在黑暗中刺伤