我有一个看起来像这样的课程:
class User < ActiveRecord:Base
has_many :users_companies
has_many :companies, :through => :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方法以适应这种行为?或者,我是否应该对在公司使用范围感到满意?
答案 0 :(得分:5)
我正在努力解决类似的问题。我可以设计的唯一可接受的解决方案是association extension,它会覆盖管理员用户的查询并传递普通用户的查询,不受干扰。
# 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
答案 1 :(得分:0)
我对Rails相当新,但这是一个有趣的问题,所以我想我会投入两分钱。您似乎应该能够使用User
方法扩展companies
中的关联,以检查self.is_admin?
(或类似)并返回您需要的内容。见http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many#461-User-a-block-to-extend-your-associations
答案 2 :(得分:0)
好问题。我想知道以下是否是你会考虑的选项
class User < ActiveRecord:Base
has_many :users_companies
has_many :companies, :through => :users_companies
def viewable_companies
admin? ? Company.all : self.companies
end
end
我知道命名是可怕的,但是,你知道,命名是严肃的事情:)