aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Noria <fxn@hashref.com>2010-02-06 22:24:38 +0100
committerXavier Noria <fxn@hashref.com>2010-02-06 22:24:38 +0100
commit55bb27adc4eb4f86979bfe3eba8a6269cb1df096 (patch)
treebe368c55c99d5052ac0744c9545a466c8daab896
parentbb818372011eec8060aee775f5bc2f402af25dab (diff)
downloadrails-55bb27adc4eb4f86979bfe3eba8a6269cb1df096.tar.gz
rails-55bb27adc4eb4f86979bfe3eba8a6269cb1df096.tar.bz2
rails-55bb27adc4eb4f86979bfe3eba8a6269cb1df096.zip
AS guides: documents Module#delegate
-rw-r--r--railties/guides/source/active_support_core_extensions.textile82
1 files changed, 80 insertions, 2 deletions
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index a62a99800b..b7aeb063fe 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -618,9 +618,87 @@ end
NOTE: Defined in +active_support/core_ext/module/attribute_accessors.rb+.
-h4. Delegation
+h4. Method Delegation
-The class method +delegate+
+The class method +delegate+ offers an easy way to forward methods.
+
+For example, if +User+ has some details like the age factored out to +Profile+, it could be handy to still be able to acces such attribute directly, <tt>user.age</tt>, instead of having to explicit the chain <tt>user.profile.age</tt>.
+
+That can be accomplished by hand:
+
+<ruby>
+class User
+ has_one :profile
+
+ def age
+ profile.age
+ end
+end
+</ruby>
+
+But with +delegate+ you can make that shorter and the intention even more obvious:
+
+<ruby>
+class User
+ has_one :profile
+
+ delegate :age, to => :profile
+end
+</ruby>
+
+The macro accepts more than one method:
+
+<ruby>
+class User
+ has_one :profile
+
+ delegate :age, :avatar, :twitter_username, to => :profile
+end
+</ruby>
+
+Methods can be delegated to objects returned by methods, as in the examples above, but also to instance variables, class variables, and constants. Just pass their names as symbols or strings, including the at signs in the last cases.
+
+For example, +ActionView::Base+ delegates +erb_trim_mode=+:
+
+<ruby>
+module ActionView
+ class Base
+ delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB'
+ end
+end
+</ruby>
+
+In fact, you can delegate to any expression passed as a string. It will be evaluated in the context of the receiver. Controllers for example delegate alerts and notices to the current flash:
+
+<ruby>
+delegate :alert, :notice, :to => "request.flash"
+</ruby>
+
+If the target is +nil+ calling any delegated method will raise an exception even if +nil+ responds to such method. You can override this behavior setting the option +:allow_nil+ to true, in which case the forwarded call will simply return +nil+.
+
+If the target is a method, the name of delegated methods can also be prefixed. If the +:prefix+ option is set to (exactly) the +true+ object, the value of the +:to+ option is prefixed:
+
+<ruby>
+class Invoice
+ belongs_to :customer
+
+ # defines a method called customer_name
+ delegate :name, :to => :customer, :prefix => true
+end
+</ruby>
+
+And a custom prefix can be set as well, in that case it does not matter wheter the target is a method or not:
+
+<ruby>
+class Account
+ belongs_to :user
+
+ # defines a method called admin_email
+ delegate :email, :to => :user, :prefix => 'admin'
+end
+</ruby>
+
+NOTE: Defined in +active_support/core_ext/module/delegation+.
h3. Extensions to +Class+