Skip to content
This repository
Browse code

Adding ActiveModel::AttributeMethods documentation

  • Loading branch information...
commit 8834b2612b7ddda70ee6a685eb0063d3daa8e63d 1 parent e1c15d9
Mikel Lindsaar authored January 17, 2010
25  activemodel/README
@@ -12,9 +12,30 @@ Active Model provides a known set of interfaces that your objects can implement
12 12
 to then present a common interface to the Action Pack helpers.  You can include
13 13
 functionality from the following modules:
14 14
 
  15
+* Adding attribute magic to your objects
  16
+
  17
+    Add prefixes and suffixes to defined attribute methods...
  18
+    
  19
+    class Person
  20
+      include ActiveModel::AttributeMethods
  21
+      
  22
+      attribute_method_prefix 'clear_'
  23
+      define_attribute_methods [:name, :age]
  24
+      
  25
+      attr_accessor :name, :age
  26
+    
  27
+      def clear_attribute(attr)
  28
+        send("#{attr}=", nil)
  29
+      end
  30
+    end
  31
+    
  32
+    ...gives you clear_name, clear_age.
  33
+  
  34
+  {Learn more}[link:classes/ActiveModel/AttributeMethods.html]
  35
+  
15 36
 * Adding callbacks to your objects
16 37
 
17  
-    class MyClass
  38
+    class Person
18 39
       extend ActiveModel::Callbacks
19 40
       define_model_callbacks :create
20 41
     
@@ -32,7 +53,7 @@ functionality from the following modules:
32 53
 
33 54
 * For classes that already look like an Active Record object
34 55
 
35  
-    class MyClass
  56
+    class Person
36 57
       include ActiveModel::Conversion
37 58
     end
38 59
     
141  activemodel/lib/active_model/attribute_methods.rb
@@ -5,10 +5,51 @@ module ActiveModel
5 5
   class MissingAttributeError < NoMethodError
6 6
   end
7 7
 
  8
+  # <tt>ActiveModel::AttributeMethods</tt> provides a way to add prefixes and suffixes
  9
+  # to your methods as well as handling the creation of Active Record like class methods
  10
+  # such as +table_name+.
  11
+  # 
  12
+  # The requirements to implement ActiveModel::AttributeMethods are:
  13
+  #
  14
+  # * <tt>include ActiveModel::AttributeMethods</tt> in your object
  15
+  # * Call each Attribute Method module method you want to add, such as 
  16
+  #   attribute_method_suffix or attribute_method_prefix
  17
+  # * Call <tt>define_attribute_methods</tt> after the other methods are
  18
+  #   called.
  19
+  # * Define the various generic +_attribute+ methods that you have declared
  20
+  # 
  21
+  # A minimal implementation could be:
  22
+  # 
  23
+  #   class Person
  24
+  #   
  25
+  #     include ActiveModel::AttributeMethods
  26
+  #     
  27
+  #     attribute_method_affix  :prefix => 'reset_', :suffix => '_to_default!'
  28
+  #     attribute_method_suffix '_contrived?'
  29
+  #     attribute_method_prefix 'clear_'
  30
+  #     define_attribute_methods ['name']
  31
+  #     
  32
+  #     attr_accessor :name
  33
+  #     
  34
+  #     private
  35
+  #     
  36
+  #     def attribute_contrived?(attr)
  37
+  #       true
  38
+  #     end
  39
+  #     
  40
+  #     def clear_attribute(attr)
  41
+  #       send("#{attr}=", nil)
  42
+  #     end
  43
+  #     
  44
+  #     def reset_attribute_to_default!(attr)
  45
+  #       send("#{attr}=", "Default Name")
  46
+  #     end
  47
+  #   
  48
+  #   end
  49
+  # 
8 50
   module AttributeMethods
9 51
     extend ActiveSupport::Concern
10 52
 
11  
-    # Declare and check for suffixed attribute methods.
12 53
     module ClassMethods
13 54
       # Defines an "attribute" method (like +inheritance_column+ or
14 55
       # +table_name+). A new (class) method will be created with the
@@ -22,12 +63,27 @@ module ClassMethods
22 63
       #
23 64
       # Example:
24 65
       #
25  
-      #   class A < ActiveRecord::Base
  66
+      #   class Person
  67
+      # 
  68
+      #     include ActiveModel::AttributeMethods
  69
+      # 
  70
+      #     cattr_accessor :primary_key
  71
+      #     cattr_accessor :inheritance_column
  72
+      #     
26 73
       #     define_attr_method :primary_key, "sysid"
27 74
       #     define_attr_method( :inheritance_column ) do
28 75
       #       original_inheritance_column + "_id"
29 76
       #     end
  77
+      # 
30 78
       #   end
  79
+      # 
  80
+      # Provivdes you with:
  81
+      # 
  82
+      #   AttributePerson.primary_key
  83
+      #   # => "sysid"
  84
+      #   AttributePerson.inheritance_column = 'address'
  85
+      #   AttributePerson.inheritance_column
  86
+      #   # => 'address_id'
31 87
       def define_attr_method(name, value=nil, &block)
32 88
         sing = metaclass
33 89
         sing.send :alias_method, "original_#{name}", name
@@ -54,19 +110,25 @@ def define_attr_method(name, value=nil, &block)
54 110
       #
55 111
       # For example:
56 112
       #
57  
-      #   class Person < ActiveRecord::Base
  113
+      #   class Person
  114
+      # 
  115
+      #     include ActiveModel::AttributeMethods
  116
+      #     attr_accessor :name
58 117
       #     attribute_method_prefix 'clear_'
  118
+      #     define_attribute_methods [:name]
59 119
       #
60 120
       #     private
61  
-      #       def clear_attribute(attr)
62  
-      #         ...
63  
-      #       end
  121
+      # 
  122
+      #     def clear_attribute(attr)
  123
+      #       send("#{attr}=", nil)
  124
+      #     end
64 125
       #   end
65 126
       #
66  
-      #   person = Person.find(1)
67  
-      #   person.name          # => 'Gem'
  127
+      #   person = Person.new
  128
+      #   person.name = "Bob"
  129
+      #   person.name          # => "Bob"
68 130
       #   person.clear_name
69  
-      #   person.name          # => ''
  131
+      #   person.name          # => nil
70 132
       def attribute_method_prefix(*prefixes)
71 133
         attribute_method_matchers.concat(prefixes.map { |prefix| AttributeMethodMatcher.new :prefix => prefix })
72 134
         undefine_attribute_methods
@@ -86,18 +148,24 @@ def attribute_method_prefix(*prefixes)
86 148
       #
87 149
       # For example:
88 150
       #
89  
-      #   class Person < ActiveRecord::Base
  151
+      #   class Person
  152
+      # 
  153
+      #     include ActiveModel::AttributeMethods
  154
+      #     attr_accessor :name
90 155
       #     attribute_method_suffix '_short?'
  156
+      #     define_attribute_methods [:name]
91 157
       #
92 158
       #     private
93  
-      #       def attribute_short?(attr)
94  
-      #         ...
95  
-      #       end
  159
+      # 
  160
+      #     def attribute_short?(attr)
  161
+      #       send(attr).length < 5
  162
+      #     end
96 163
       #   end
97 164
       #
98  
-      #   person = Person.find(1)
99  
-      #   person.name           # => 'Gem'
100  
-      #   person.name_short?    # => true
  165
+      #   person = Person.new
  166
+      #   person.name = "Bob"
  167
+      #   person.name          # => "Bob"
  168
+      #   person.name_short?   # => true
101 169
       def attribute_method_suffix(*suffixes)
102 170
         attribute_method_matchers.concat(suffixes.map { |suffix| AttributeMethodMatcher.new :suffix => suffix })
103 171
         undefine_attribute_methods
@@ -118,16 +186,21 @@ def attribute_method_suffix(*suffixes)
118 186
       #
119 187
       # For example:
120 188
       #
121  
-      #   class Person < ActiveRecord::Base
  189
+      #   class Person
  190
+      # 
  191
+      #     include ActiveModel::AttributeMethods
  192
+      #     attr_accessor :name
122 193
       #     attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
  194
+      #     define_attribute_methods [:name]
123 195
       #
124 196
       #     private
125  
-      #       def reset_attribute_to_default!(attr)
126  
-      #         ...
127  
-      #       end
  197
+      # 
  198
+      #     def reset_attribute_to_default!(attr)
  199
+      #       ...
  200
+      #     end
128 201
       #   end
129 202
       #
130  
-      #   person = Person.find(1)
  203
+      #   person = Person.new
131 204
       #   person.name                         # => 'Gem'
132 205
       #   person.reset_name_to_default!
133 206
       #   person.name                         # => 'Gemma'
@@ -146,6 +219,30 @@ def #{matcher.method_name(new_name)}(*args)
146 219
         end
147 220
       end
148 221
 
  222
+      # Declares a the attributes that should be prefixed and suffixed by 
  223
+      # ActiveModel::AttributeMethods.
  224
+      # 
  225
+      # To use, pass in an array of attribute names (as strings or symbols),
  226
+      # be sure to declare +define_attribute_methods+ after you define any
  227
+      # prefix, suffix or affix methods, or they will not hook in.
  228
+      # 
  229
+      #   class Person
  230
+      # 
  231
+      #     include ActiveModel::AttributeMethods
  232
+      #     attr_accessor :name, :age, :address
  233
+      #     attribute_method_prefix 'clear_'
  234
+      #
  235
+      #     # Call to define_attribute_methods must appear after the
  236
+      #     # attribute_method_prefix, attribute_method_suffix or
  237
+      #     # attribute_method_affix declares.
  238
+      #     define_attribute_methods [:name, :age, :address]
  239
+      #
  240
+      #     private
  241
+      # 
  242
+      #     def clear_attribute(attr)
  243
+      #       ...
  244
+      #     end
  245
+      #   end
149 246
       def define_attribute_methods(attr_names)
150 247
         return if attribute_methods_generated?
151 248
         attr_names.each do |attr_name|
@@ -168,6 +265,7 @@ def #{matcher.method_name(attr_name)}(*args)
168 265
         @attribute_methods_generated = true
169 266
       end
170 267
 
  268
+      # Removes all the preiously dynamically defined methods from the class
171 269
       def undefine_attribute_methods
172 270
         generated_attribute_methods.module_eval do
173 271
           instance_methods.each { |m| undef_method(m) }
@@ -183,6 +281,7 @@ def generated_attribute_methods #:nodoc:
183 281
         end
184 282
       end
185 283
 
  284
+      # Returns true if the attribute methods defined have been generated.
186 285
       def attribute_methods_generated?
187 286
         @attribute_methods_generated ||= nil
188 287
       end

0 notes on commit 8834b26

Please sign in to comment.
Something went wrong with that request. Please try again.