Query guide: scopes with arguments should be instead defined as class methods.

This commit is contained in:
Ryan Bigg 2010-12-23 14:57:53 +10:00
parent b4b2574a12
commit 0644e38c42

@ -768,13 +768,41 @@ h4. Working with times
If you're working with dates or times within scopes, due to how they are evaluated, you will need to use a lambda so that the scope is evaluated every time. If you're working with dates or times within scopes, due to how they are evaluated, you will need to use a lambda so that the scope is evaluated every time.
<ruby> <ruby>
class Post < ActiveRecord::Base class Post < ActiveRecord::Base
scope :last_week, lambda { where("created_at < ?", Time.zone.now ) } scope :last_week, lambda { where("created_at < ?", Time.zone.now ) }
end end
</ruby> </ruby>
Without the +lambda+, this +Time.zone.now+ will only be called once. Without the +lambda+, this +Time.zone.now+ will only be called once.
h4. Passing in arguments
When a +lambda+ is used for a +scope+, it can take arguments:
<ruby>
class Post < ActiveRecord::Base
scope :1_week_before, lambda { |time| where("created_at < ?", time)
end
</ruby>
This may then be called using this:
<ruby>
Post.1_week_before(Time.zone.now)
</ruby>
However, this is just duplicating the functionality that would be provided to you by a class method.
<ruby>
class Post < ActiveRecord::Base
def self.1_week_before(time)
where("created_at < ?", time)
end
end
</ruby>
Using a class method is the preferred way to accept arguments for scopes.
h3. Dynamic Finders h3. Dynamic Finders
For every field (also known as an attribute) you define in your table, Active Record provides a finder method. If you have a field called +first_name+ on your +Client+ model for example, you get +find_by_first_name+ and +find_all_by_first_name+ for free from Active Record. If you have a +locked+ field on the +Client+ model, you also get +find_by_locked+ and +find_all_by_locked+ methods. For every field (also known as an attribute) you define in your table, Active Record provides a finder method. If you have a field called +first_name+ on your +Client+ model for example, you get +find_by_first_name+ and +find_all_by_first_name+ for free from Active Record. If you have a +locked+ field on the +Client+ model, you also get +find_by_locked+ and +find_all_by_locked+ methods.