147
votes

I'm wondering how the following is done in Rails 4 or if I just use the Rails 3 approach for using a lambda that can pass an argument the same way with 4 as I do with 3.

I'm pretty new to Rails 3 and trying to work through some samples running Rails 4.

Here is my Rails 3 code:

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

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

So if this is the Rails 4 way is to use the -> {}, that's a lambda, right? scope :all_lazy, -> { select("*") } What if I needed an argument. I tried a few different ideas and get argument errors in the console when using the -> {}.

6

6 Answers

312
votes

I think it should be:

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

Ruby has not deprecated the old style of lambda either, so if you feel more comfortable using that by all means go for it.

I don't personally like the stabby lambda's syntax myself but eventually they will probably become the norm so it doesn't hurt to get used to them.

8
votes

Rails 4, you can do:

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

That was in the old ruby:

:id => id

Better hash:

id: id
5
votes

guy I was usually using the below programming syntax

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

But when I was reviewing my code using Codacy I found it alerting me about this syntax

Use the `lambda` method for multiline lambdas.

I changed it to be and it working well

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

To support associations:

scope :find_lazy, -> (object) { where(object_id: object.id) }
2
votes
scope :find_lazy, -> (id) { where(id: id) }

is equivalent with

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

Based on ruby on rails guide: Using a class method is the preferred way to accept arguments for scopes.

There is no reason to use scopes together with lambdas in preference to class methods. It is a matter of personal preference. But, if you want to follow the guidelines, you should use the class method when arguments are involved.