在我的ApplicationController
我有demo_mode?
方法(当前登录的用户类型为“demo”时返回true
)。
Post
模型具有publisher_id
字段,该字段引用Users
表。
User
有user_type
字段,其中一个可能的值是“demo”。
底线:帖子p
由“演示”用户发布,当且仅当:
User.find(p.publisher_id).user_type == "demo"
我想创建一个将返回的命名范围Post.relevant
:
demo_mode? == true
demo_mode? == false
您将如何创建这样的命名范围?我应该将demo_mode?
移到其他地方吗?
答案 0 :(得分:2)
使用lambda创建动态范围,并将会话信息保留在模型之外:
在你的模特中:
class Post < ActiveRecord::Base
scope :relevant, lambda {|demo_mode|
joins(:publisher).
where("publishers.user_type #{demo_mode ? '' : 'NOT'} LIKE 'demo'")
}
end
然后在控制器中:
posts = Post.relevant(demo_mode?)
答案 1 :(得分:0)
尝试这样的事情
class Post < ActiveRecord::Base
scope :relevant, joins("INNER JOIN users ON (users.user_type = 'demo')").where("publisher_id = users.id")
end
答案 2 :(得分:0)
如果我理解正确,演示状态由会话决定,因此只有控制器知道它。另一方面,控制器(或可能是视图)是您想要查询范围的唯一位置。如果所有这些都是正确的,我会向ApplicationController添加一个方法,如下所示:
class ApplicationController < ActionController::Base
def relevant_posts
Post.joins(:publisher).
where("publishers.user_type #{demo_mode? ? '' : 'NOT'} LIKE 'demo'")
end
...
helper_method :relevant_posts # if you want it to be available in views
end
从技术上讲,这不是命名范围。但是,Rails 3在命名范围和标准查询接口之间没有太大区别。