Rails 4风格中使用lambda和参数的作用域?

148

我想知道在Rails 4中如何完成以下操作,或者我是否应该使用在Rails 3中使用lambda的方法,并且可以在4中与3一样传递参数。

我对Rails 3比较陌生,正在尝试运行Rails 4的一些示例。

这是我的Rails 3代码:

class Person < ActiveRecord::Base
  scope :find_lazy, lambda {|id| where(:id => id)}
end

# In console I can call
Person.find_lazy(1)

所以,如果这是Rails 4的方法,使用-> {},那么这是一个lambda,对吗?scope :all_lazy, -> { select("*") }如果我需要一个参数呢?我尝试了一些不同的想法,在使用-> {}时在控制台上会收到参数错误。

6个回答

315

我认为应该是:

scope :find_lazy, -> (id) { where(id: id) }

2
支持文档:http://guides.rubyonrails.org/active_record_querying.html#scopes,特别是第14.1节。 - Dennis
4
耶,帮我写了 scope :in_daterange, ->(start_date, end_date) { where(created_at: start_date.to_date.beginning_of_day..end_date.to_date.end_of_day) } - Epigene
5
请注意,如果你正在使用 Ruby 1.9 版本,短 lambda 语法不允许在箭头和参数之间放置空格 (scope :find_lazy, ->(param))。在 Ruby 2+ 版本中,可以添加空格。更多信息请点击这里... - furman87
在 Ruby 中的“现代”语法 scope :find_lazy, -> id { where id: id } - swordray

11

Ruby并没有弃用旧式lambda,所以如果您更喜欢使用它,请放心使用。

个人而言,我不太喜欢箭头lambda的语法,但最终它们可能会成为常规用法,所以习惯一下也无妨。


6
我喜欢这个语法,但在箭头和函数体之间放置参数感觉很奇怪,应该是“(id) -> { where ... }”,这样更有吸引力(而且不会与我的数学知识或咖啡脚本语法冲突)。最终,“->”的意思类似于将值映射到结果。 - hurikhan77
我遇到了一个情况,在Rails 4.2中使用旧的语法从数据库返回了不正确的布尔值。虽然它可能没有被正式弃用,但使用更新的语法解决了这个问题。 - stevenspiel
1
@hurikhan77 是的,语法与CoffeeScript冲突有点令人不安。http://coffeescript.org/#functions - Chloe

8
Rails 4中,你可以做到:
scope :find_lazy, -> (id) { where(id: id) }

这是在旧版 Ruby 中的写法:

:id => id

更优的哈希算法:
id: id

6

我通常使用以下编程语法:

scope :find_lazy, -> (id) { where(id: id) }

但是当我使用Codacy审查我的代码时,发现它警告我关于这个语法的问题。
Use the `lambda` method for multiline lambdas.

我将其更改为这样,现在它运行良好。

  scope :find_lazy, lambda {|id|
    where(id: id)
  }

2
支持关联:
scope :find_lazy, -> (object) { where(object_id: object.id) }

2
scope :find_lazy, -> (id) { where(id: id) }

is equivalent with

self.find_lazy(id)
  where(id: id)
end

根据Ruby on Rails指南:使用类方法是接受作用域参数的首选方式。 没有理由优先使用带有lambda的作用域,而不是类方法。这是个人偏好的问题。但是,如果你想遵循指南,当涉及到参数时,应该使用类方法。最初的回答。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接