何时何时不将lambda用于命名范围?

时间:2014-10-23 12:30:24

标签: ruby-on-rails ruby

我希望了解lambda对这个命名范围的影响:

我的模型上定义了两个范围:

scope :credits, lambda { where("comparison_ind != 'PEER'")}

vs

scope :credits, where("comparison_ind != 'PEER'")

这两个陈述有什么区别? comparison_ind是属于同一模型的列。

1 个答案:

答案 0 :(得分:4)

在Rails 4中

始终使用lambda 。第二种语法在Rails 4中是不正确的并且会抛出错误(对于ActiveRecord :: Relation,未定义的方法'call')

# activerecord/lib/active_record/scoping/named.rb
scope = all.scoping { body.call(*args) }

在Rails 3中

scope方法在两种情况下都表现相同 - 它创建了一个名为credits的新类方法。区别在于,当给定lambda时,每次调用此新方法获取范围时,它都会计算此lambda,而在给定关系时,它只使用已传递的内容。

# activerecord/lib/active_record/named_scope.rb
options = scope_options.respond_to?(:call) ? scope_options.call(*args) : scope_options

在这种情况下,lambda总是返回完全相同的关系,因此不会注意到差异。

Lambda表示法通常用于将参数传递给范围:

scope :before, lambda {|date| where.created_at < date}

然后可以使用:

Model.before(1.day.ago)

如果没有lambda,这自然是不可能的。