Ruby-on-rails 带参数的 Rails 4 范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23412719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:35:53  来源:igfitidea点击:

Rails 4 scope with argument

ruby-on-railsruby-on-rails-4

提问by Victor

Upgrading Rails 3.2. to Rails 4. I have the following scope:

升级 Rails 3.2。到 Rails 4。我有以下范围:

# Rails 3.2
scope :by_post_status, lambda { |post_status| where("post_status = ?", post_status) }
scope :published, by_post_status("public")
scope :draft, by_post_status("draft")

# Rails 4.1.0
scope :by_post_status, -> (post_status) { where('post_status = ?', post_status) }

But I couldn't find out how to do the 2nd and 3rd lines. How can I create another scope from the first scope?

但我不知道如何做第 2 行和第 3 行。如何从第一个范围创建另一个范围?

回答by Зелёный

Very simple, just same lambda without arguments:

非常简单,就是没有参数的相同 lambda:

scope :by_post_status, -> (post_status) { where('post_status = ?', post_status) }
scope :published, -> { by_post_status("public") }
scope :draft, -> { by_post_status("draft") }

or more shorted:

或更短:

%i[published draft].each do |type|
  scope type, -> { by_post_status(type.to_s) }
end

回答by wvandaal

From the Rails edge docs

来自Rails 边缘文档

"Rails 4.0 requires that scopes use a callable object such as a Proc or lambda:"

“Rails 4.0 要求作用域使用可调用对象,例如 Proc 或 lambda:”

scope :active, where(active: true)

# becomes 
scope :active, -> { where active: true }



With this in mind, you can easily rewrite you code as such:

考虑到这一点,您可以轻松地重写代码:

scope :by_post_status, lambda { |post_status| where('post_status = ?', post_status) }
scope :published, lambda { by_post_status("public") }
scope :draft, lambda { by_post_status("draft") }

In the event that you have many different statuses that you wish to support and find this to be cumbersome, the following may suit you:

如果您有许多不同的状态想要支持并且觉得这很麻烦,那么以下可能适合您:

post_statuses = %I[public draft private published ...]
scope :by_post_status, -> (post_status) { where('post_status = ?', post_status) }

post_statuses.each {|s| scope s, -> {by_post_status(s.to_s)} }