是否可以有一个带有可选参数的范围?
Posted
技术标签:
【中文标题】是否可以有一个带有可选参数的范围?【英文标题】:Is it possible to have a scope with optional arguments? 【发布时间】:2012-05-07 11:47:27 【问题描述】:是否可以编写一个带有可选参数的作用域,以便我可以调用带参数和不带参数的作用域?
类似:
scope :with_optional_args, lambda |arg|
where("table.name = ?", arg)
Model.with_optional_args('foo')
Model.with_optional_args
如果给定了 arg(如 Unixmonkey 所述),我可以检查 lambda 块,但是在没有参数的情况下调用范围时,我得到了 ArgumentError: wrong number of arguments (0 for 1)
【问题讨论】:
【参考方案1】:几周前我使用了scope :name, ->(arg1, arg2 = value) ...
,如果我没记错的话,它运行良好。与 ruby 1.9+ 一起使用
【讨论】:
【参考方案2】:使用 *
scope :with_optional_args, -> |*arg| where("table.name = ?", arg)
【讨论】:
【参考方案3】:您可以根据给定的参数有条件地修改您的范围。
scope :random, ->(num = nil) num ? order('RANDOM()').limit(num) : order('RANDOM()')
用法:
Advertisement.random # => returns all records randomized
Advertisement.random(1) # => returns 1 random record
或者,您可以提供一个默认值。
scope :random, ->(num = 1000) order('RANDOM()').limit(num)
用法:
Product.random # => returns 1,000 random products
Product.random(5) # => returns 5 random products
注意:RANDOM()
显示的语法特定于 Postgres。显示的语法是 Rails 4。
【讨论】:
【参考方案4】:当然。
scope :with_optional_args, Proc.new |arg|
if arg.present?
where("table.name = ?", arg)
end
【讨论】:
你不想在没有参数传递时包含一个后备吗? 如果我不传递参数,我得到一个错误:ArgumentError: wrong number of arguments (0 for 1) 您可以使用 Proc.new 而不是 lambda 来避免参数错误。请参阅有关此 here 的旧讨论【参考方案5】:只是想让您知道,根据guide,将参数传递给作用域的推荐方法是使用类方法,如下所示:
class Post < ActiveRecord::Base
def self.1_week_before(time)
where("created_at < ?", time)
end
end
这可以提供更简洁的方法。
【讨论】:
【参考方案6】:Ruby 1.9 扩展块具有与方法相同的功能(其中包含默认值):
scope :cheap, lambda|max_price=20.0| where("price < ?", max_price)
呼叫:
Model.cheap
Model.cheap(15)
【讨论】:
【参考方案7】:是的。只需像在方法中一样使用*
。
scope :print_args, lambda |*args|
puts args
【讨论】:
以上是关于是否可以有一个带有可选参数的范围?的主要内容,如果未能解决你的问题,请参考以下文章