Nick Kallen noted that the behavior of has_many_with_args can be accomplished using has_finder.
Too true!
Imagine a system in which Users send Whispers to one another. We would like to see Whispers scoped so that:
-
A User viewing their own Whispers should see all Whispers they have received
-
A User viewing another User’s Whispers should see only Whispers they themselves sent
With the clean chainable syntax provided by has_finder, this is straight-forward. We return associations directly (notice, no find calls) and isolate declaration of the scoping the behavior to the class affected by it.
class Whisper < ActiveRecord::Base has_finder :from, lambda { |sender| { :conditions => [ 'sender_id = ?', sender.id ] } } end class User < ActiveRecord::Base has_many :received_whispers, :foreign_key => 'recipient_id' def whispers_viewable_by user return whispers if self == user whispers.from(user) end end
How expressive is that? Business rules are cleanly captured in the models and our associations stay so limber!
Thanks to Pat Maddox for turning me on to has_finder, and Nick Kallen for writing it.
Leave a Comment