是否可以使用可选参数作用域?

时间:2012-04-26 17:42:49

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

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

类似的东西:

scope :with_optional_args,  lambda { |arg|
  where("table.name = ?", arg)
}

Model.with_optional_args('foo')
Model.with_optional_args

我可以检查lambda块是否给出了arg(如Unixmonkey所描述)但是在没有参数的情况下调用范围时我得到了ArgumentError: wrong number of arguments (0 for 1)

7 个答案:

答案 0 :(得分:23)

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

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

呼叫:

Model.cheap
Model.cheap(15)

答案 1 :(得分:19)

是。只需像在方法中一样使用*

scope :print_args, lambda {|*args|
    puts args
}

答案 2 :(得分:12)

我几周前使用scope :name, ->(arg1, arg2 = value) { ... },如果记忆正确,它运作良好。与ruby 1.9 +一起使用

答案 3 :(得分:8)

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

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 :(得分:4)

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

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

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

答案 5 :(得分:1)

当然可以。

scope :with_optional_args,  Proc.new { |arg|
  if arg.present?
    where("table.name = ?", arg)
  end
}

答案 6 :(得分:0)

使用*

scope :with_optional_args,  -> { |*arg| where("table.name = ?", arg) }