Rails 3:如何根据Controller的方法创建命名范围?

时间:2011-05-20 12:55:40

标签: ruby-on-rails ruby-on-rails-3 named-scope

在我的ApplicationController我有demo_mode?方法(当前登录的用户类型为“demo”时返回true)。

Post模型具有publisher_id字段,该字段引用Users表。

Useruser_type字段,其中一个可能的值是“demo”。

底线:帖子p由“演示”用户发布,当且仅当:

User.find(p.publisher_id).user_type == "demo"

我想创建一个将返回的命名范围Post.relevant

  • “演示”用户发布的所有帖子,如果demo_mode? == true
  • 非“演示”用户发布的所有帖子,如demo_mode? == false

您将如何创建这样的命名范围?我应该将demo_mode?移到其他地方吗?

3 个答案:

答案 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在命名范围和标准查询接口之间没有太大区别。