我有一个应用程序,其中公司和用户需要通过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})
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 theincludes
method of
theModel.find
call. With includes,
Active Record ensures that all of the
specified associations are loaded
using the minimum possible number of
queries.queries. 07000
(我仍然愿意接受任何人的建议,认为这不是最好的/最有效的/正确的方式.)