23

是否可以编写带有可选参数的范围,以便我可以使用和不使用参数来调用范围?

就像是:

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)

4

7 回答 7

28

Ruby 1.9 扩展块具有与方法相同的功能(其中包含默认值):

scope :cheap, lambda{|max_price=20.0| where("price < ?", max_price)}

称呼:

Model.cheap
Model.cheap(15)
于 2012-04-26T19:05:58.150 回答
22

是的。只需*在方法中使用 a 即可。

scope :print_args, lambda {|*args|
    puts args
}
于 2012-04-26T18:52:06.230 回答
14

scope :name, ->(arg1, arg2 = value) { ... }几周前用过,如果我没记错的话,效果很好。与 ruby​​ 1.9+ 一起使用

于 2012-04-26T18:48:24.360 回答
11

您可以根据给定的参数有条件地修改您的范围。

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。

于 2014-08-20T16:47:12.060 回答
4

只是想让您知道,根据指南,将参数传递给作用域的推荐方法是使用类方法,如下所示:

class Post < ActiveRecord::Base
  def self.1_week_before(time)
    where("created_at < ?", time)
  end
end

这可以提供更清洁的方法。

于 2013-02-11T23:59:44.460 回答
1

当然。

scope :with_optional_args,  Proc.new { |arg|
  if arg.present?
    where("table.name = ?", arg)
  end
}
于 2012-04-26T17:59:31.590 回答
0

使用 *

scope :with_optional_args,  -> { |*arg| where("table.name = ?", arg) }
于 2016-07-14T19:18:32.647 回答