我的架构看起来像这样(简化):我的用户拥有不同的权限,可以创建经历某个生命周期的帖子(创建,审核,关闭,类似的东西......)。
以rails语言说class User has_many :posts
,但我希望用户根据自己的权限查看帖子。如果用户享有特权,他应该能够看到所有帖子,如果不是,我希望他只看到已经审核过的帖子以及他自己的所有帖子。
现在,Post模型有一个类方法for_user(user)
,它只检查用户权限并返回相应的帖子。我理解,这不是Rails的方式,而是我想知道是否可以这样做:
class User
has_many :posts, :finder_sql => finder
#[...]
def finder
if self.has_privileges? #simplified...
all
else
where( '[...]' )
end
end
不幸的是,这不起作用,因为rails期望:finder_sql只是一个字符串和一个字符串。有没有其他方法可以创建所需的行为?
答案 0 :(得分:1)
我在当前的应用程序中做了类似的事情,我发现使用CanCan makes it very easy。
当然,将您的权限逻辑转移到CanCan可能需要更多的努力,但它确实增加了很多灵活性。如果不出意外,您可以查看源代码以了解他是如何做到的。
答案 1 :(得分:0)
一种可能的方法是创建一个别名方法“all_posts”,然后定义自己的使用它的帖子方法:
class User
has_many :all_posts, :class_name => "Post"
def posts
self.has_priviledges? ? self.all_posts : self.all_posts.where(...)
end
end
这样做的缺点是失去了ActiveRecord为你做的一些缓存。例如,如果你两次调用user.all_posts,那么只有第一个调用sql,但是如果使用了where子句,则调用user.posts两次可能会两次调用sql。
答案 2 :(得分:0)
不是使用has_many
关联(它添加了一堆setter方法,以及getter),而是简单地定义一个方法(你或多或少已经完成了):
def User < ActiveRecord::Base
has_many :posts # written by the user
# Posts the user can see
def posts_visible_to
if has_privileges?
Post.all
else
posts
end
end
end
PS你错误拼写'特权'...... :)