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

发布于 2024-11-08 20:09:00 字数 658 浏览 7 评论 0原文

在我的 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? 移动到其他地方吗?

In my ApplicationController I have the demo_mode? method (which returns true when the currently logged in user type is "demo").

Post model has the publisher_id field, which refers to Users table.

User has the user_type field, one of the possible values of which is "demo".

Bottom line: post p was published by a "demo" user if and only if:

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

I would like to create a named scope Post.relevant that will return:

  • all posts that were published by "demo" users, if demo_mode? == true
  • all posts that were published by non "demo" users, if demo_mode? == false

How would you create such a named scope ? Should I move demo_mode? to other place ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

锦欢 2024-11-15 20:09:00

使用 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?)

Use a lambda to make a dynamic scope, and keep the session info out of the model:

In your model:

class Post < ActiveRecord::Base
  scope :relevant, lambda {|demo_mode|
     joins(:publisher).
     where("publishers.user_type #{demo_mode ? '' : 'NOT'} LIKE 'demo'")
  }
end

And then in the controller:

posts = Post.relevant(demo_mode?)
夏末 2024-11-15 20:09:00

尝试这样的事情

class Post < ActiveRecord::Base

    scope :relevant, joins("INNER JOIN users ON (users.user_type = 'demo')").where("publisher_id = users.id")

end

Try something like this

class Post < ActiveRecord::Base

    scope :relevant, joins("INNER JOIN users ON (users.user_type = 'demo')").where("publisher_id = users.id")

end
场罚期间 2024-11-15 20:09:00

如果我理解正确的话,演示状态是由会话决定的,因此只有控制器知道它。另一方面,控制器(或者可能是视图)是您想要查询范围的唯一位置。如果所有这些都是正确的,我将向 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 在命名范围和标准查询接口之间没有太大区别。

If I understand correctly, the demo state is determined by the session so only the controller knows about it. On the other hand, the controller (or possibly the view) is the only place where you would want to query the scope. If all of this is correct, I would add a method to ApplicationController like this:

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

Technically, this is not a named scope. Rails 3, however does not make much of a difference between named scopes and the standard query interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文