在我们的网站中,有一个常见的模型,比如视频,它有许多属性,如私人/公共/待定,可下载等。
根据控制器,操作,请求参数和当前用户,我们希望从显示中过滤掉特定的视频。例如,在主页上我们只想显示公开的视频。如果主页上有登录用户,我们还希望显示公共可下载视频。
我们还希望确保这些过滤器可以单独通过sql查询应用,这样使用Sphinx时我们可以在用户在网站上搜索时过滤掉不需要的视频。
最好通过授权插件处理,例如rails-authorization-plugin?最重要的是,我们的目标是防止程序员在添加新操作时意外忘记过滤掉特定视频。我们正在寻找的解决方案应该是非常有条理的。
这是我正在考虑的解决方案(尚未编写任何代码)
使用authroization插件或滚动我们自己的插件,允许设置显示哪些视频,在控制器或操作级别定义。
为has_many(:videos)或has_one(:video)的任何模型创建关联扩展,这样我们就可以为关联中的视频重载查找器。
以类似的方式重载Video.find,以根据当前规则限制显示内容。
答案 0 :(得分:3)
您的一般策略看似合理,但我强烈建议您不要覆盖rails默认查找器。相反,这是我过去做过的事情:
class Video < ActiveRecord::Base
named_scope :available_to, lambda {|user|
if user.nil?
:conditions => {:public_accessible => true}
elsif user.omnipotent?
{}
else
:conditions => [%{
videos.public_accessible = ? OR EXISTS (
....boring security stuff linking to users....
)
}, true, user.id]
end
}
end
然后在video_shop.rb中:
class VideoShop < ActiveRecord::Base
has_many :videos
end
最后,把它们放在一起:
# All videos available to a user
Video.available_to(user)
# All videos in a given shop
video_shop.videos
# All videos in a given shop available to a given user
video_shop.videos.available_to(user)
请注意,即使用户为零,这些也能正常工作。