修改has_many的行为还是使用scope?

我有一个看起来像这样的类:

class User  :users_companies end 

对于普通用户,我希望user.companies引用标准关联方法,但是当用户是管理员时,我想要User.all (即管理员可以访问所有公司)。 我能想到的最简单的方法是实现这个(以及我过去一直做的)是在Company类上使用一个范围,例如:

 scope :accessible_by, lambda { |user| ... } 

唯一的问题是,这感觉不对。 而不是编写包含以下内容的控制器操作:

  @companies = Company.accessible_by(current_user) 

我觉得写作更舒服

  @companies = current_user.companies 

有没有一种方法可以覆盖User#companies方法以适应这种行为? 或者,我是否应该对使用公司范围感到满意?

我正在努力解决类似的问题。 我可以设计的唯一可接受的解决方案是关联扩展 ,它会覆盖管理员用户的查询并传递普通用户的查询,不受干扰。

 # this works for me in rails 3.1 class User < ActiveRecord:Base has_many :users_companies has_many :companies, :through => :users_companies do def visible if proxy_association.owner.admin? UsersCompany.scoped else self end end end end User.where(:admin => true).first.companies.visible == UsersCompany.all 

我对Rails相当新,但这是一个有趣的问题,所以我想我会投入两美分。 您似乎应该能够User检查self.is_admin?companies方法扩展您在User的关联self.is_admin? (或类似的)并返回您需要的内容。 请参阅http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many#461-User-a-block-to-extend-your-associations

好问题。 我想知道以下是否是您会考虑的选项

 class User < ActiveRecord:Base has_many :users_companies has_many :companies, :through => :users_companies def viewable_companies admin? ? Company.all : self.companies end end 

我知道命名是可怕的但是,你知道,命名的东西是严肃的东西:)