activerecord – 通过Rails 3中的has_many:通过关系过滤子对象

前端之家收集整理的这篇文章主要介绍了activerecord – 通过Rails 3中的has_many:通过关系过滤子对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问候,

我有一个应用程序,其中公司和用户需要通过CompanyMembership模型相互关联,其中包含有关成员资格的额外信息(具体来说,用户是否是公司的管理员,通过布尔值管理员).一个简单的代码版本:

class CompanyMembership < ActiveRecord::Base
  belongs_to :company
  belongs_to :user
end

class Company < ActiveRecord::Base
  has_many :company_memberships
  has_many :users,:through => :company_memberships
end

class User < ActiveRecord::Base
  has_many :company_memberships
  has_many :companies,:through => :company_memberships
end

当然,这使得通过company.users.all等获得公司的所有成员变得简单.但是,我正在尝试获得一个公司的所有用户的列表,该公司是该公司的管理员(并且还要测试用户是否是给定公司的管理员).我的第一个解决方案是在company.rb中如下:

def admins
  company_memberships.where(:admin => true).collect do |membership|
    membership.user
  end
end

def is_admin?(user)
    admins.include? user
end

虽然这样做是有效的,但它对每个成员进行迭代,每次都执行sql,对吗?或者说Relation比这更聪明吗?),我不知道是否有更好的方法解决(也许使用范围或Rails 3使用的新的Relation对象).

任何有关最佳程序(最好使用Rails 3最佳做法)的建议将不胜感激!

解决方法

我相信我是错误的方式,指定公司成员而不是用户的条件,这是我实际想要的(用户列表,而不是公司成员名单).我想我正在寻找的解决方案是:
users.where(:company_memberships => {:admin => true})

生成以下sql(对于ID为1的公司):

SELECT "users".* FROM "users"
  INNER JOIN "company_memberships"
    ON "users".id = "company_memberships".user_id
  WHERE (("company_memberships".company_id = 1))
    AND ("company_memberships"."admin" = 't')

我还不确定是否需要它,但是include()方法将执行急切的加载来减少SQL查询数量,如果需要的话:

Active Record lets you specify in
advance all the associations that are
going to be loaded. This is possible
by specifying the includes method of
the Model.find call. With includes,
Active Record ensures that all of the
specified associations are loaded
using the minimum possible number of
queries.queries. 07000

(我仍然愿意接受任何人的建议,认为这不是最好的/最有效的/正确的方式.)

猜你在找的Ruby相关文章