aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Noria <fxn@hashref.com>2009-08-22 02:07:41 +0200
committerXavier Noria <fxn@hashref.com>2009-08-22 02:08:21 +0200
commit7ca7dad434e0a1461302045399a4dee4af48b5b8 (patch)
tree5f58d8da3194a00d90777936d0fd9c1195f8ae5c
parentc52be361484f5a0df7e413bc6640cf1d4bcb5ef5 (diff)
downloadrails-7ca7dad434e0a1461302045399a4dee4af48b5b8.tar.gz
rails-7ca7dad434e0a1461302045399a4dee4af48b5b8.tar.bz2
rails-7ca7dad434e0a1461302045399a4dee4af48b5b8.zip
AS guide: documents aliasing
-rw-r--r--railties/guides/source/active_support_overview.textile61
1 files changed, 60 insertions, 1 deletions
diff --git a/railties/guides/source/active_support_overview.textile b/railties/guides/source/active_support_overview.textile
index 10e098b029..bad23fe6d9 100644
--- a/railties/guides/source/active_support_overview.textile
+++ b/railties/guides/source/active_support_overview.textile
@@ -435,7 +435,66 @@ end
h3. Extensions to +Module+
-...
+h4. Aliasing
+
+h5. +alias_method_chain+
+
+Using plain Ruby you can wrap methods with other methods, that's called _alias chaining_.
+
+For example, let's say you'd like params to be strings in functional tests, as they are for real requests, but still want the convenience of assigning integers and other kind of values. To accomplish that you could wrap +process+ this way in +test/test_helper.rb+:
+
+<ruby>
+ActionController::TestCase.class_eval do
+ # save a reference to the original process method
+ alias_method :original_process, :process
+
+ # now redefine process and delegate to original_process
+ def process(action, params=nil, session=nil, flash=nil, http_method='GET')
+ params_str = {}
+ params.each {|k,v| params_str[k] = v.to_s}
+ original_process(action, params_str, session, flash, http_method)
+ end
+end
+</ruby>
+
+That's the method +get+, +post+, etc., delegate the work to.
+
+That technique has a risk, it could be the case that +:original_process+ was taken. To try to avoid collisions people choose some label that characterizes what they are doing and use this pattern:
+
+<ruby>
+ActionController::TestCase.class_eval do
+ def process_with_stringfied_parameters(...)
+ ...
+ end
+ alias_method :process_without_stringfied_parameters, :process
+ alias_method :process, :process_with_stringfied_parameters
+end
+</ruby>
+
+The method +alias_method_chain+ provides a shortcut for that idiom:
+
+<ruby>
+ActionController::TestCase.class_eval do
+ def process_with_stringfied_parameters(...)
+ ...
+ end
+ alias_method_chain :process, :stringfied_parameters
+end
+</ruby>
+
+Rails uses +alias_method_chain+ all over the code base. For example validations are added to +ActiveRecord::Base#save+ by wrapping the method that way in a separate module specialised in validations.
+
+h5. +alias_attribute+
+
+Model attributes have a reader, a writer, and a predicate. You can aliase an attribute like that and have the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (same order than in assigments is my mnemonic):
+
+<ruby>
+class User < ActiveRecord::Base
+ # let me refer to the email column as "login",
+ # much meaningful for authetication code
+ alias_attribute :login, :email
+end
+</ruby>
h3. Extensions to +Class+