with_options
with_options(options)An elegant way to factor duplication out of options passed to a series of method calls. Each method called in the block, with the block variable as the receiver, will have its options merged with the default options hash provided. Each method called on the block variable must take an options hash as its final argument.
with_options :order => 'created_at', :class_name => 'Comment' do |post| post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all post.has_many :unapproved_comments, :conditions => ['approved = ?', false] post.has_many :all_comments end
Can also be used with an explicit receiver:
map.with_options :controller => "people" do |people| people.connect "/people", :action => "index" people.connect "/people/:id", :action => "show" end
3Notes
Nested with_options
You can nest with_options blocks, and you can even use the same name for the block parameter each time. E.g.:
class Product
with_options :dependent => :destroy do |product|
product.with_options :class_name => 'Media' do |product|
product.has_many :images, :conditions => {:content_type => 'image'}
product.has_many :videos, :conditions => {:content_type => 'video'}
end
product.has_many :comments
end
end
This can be useful for conditional validation
Beware nested with_options clobbers!
Careful: with_options :foo => :bar do |something| something.with_options :foo => :baz do |inner| what_is(:foo) end end
:foo will be :baz. It will not be [:bar, :baz], for example.
This bit me when trying to do nested with_options for validation where both had :if => something.