Module: ActiveModel::AttributeMethods::ClassMethods
- Defined in:
- activemodel/lib/active_model/attribute_methods.rb
Defined Under Namespace
Classes: AttributeMethodMatcher
Instance Method Summary collapse
- #alias_attribute(new_name, old_name) ⇒ Object
-
#attribute_method_affix(*affixes) ⇒ Object
Declares a method available for all attributes with the given prefix and suffix.
-
#attribute_method_prefix(*prefixes) ⇒ Object
Declares a method available for all attributes with the given prefix.
-
#attribute_method_suffix(*suffixes) ⇒ Object
Declares a method available for all attributes with the given suffix.
-
#define_attr_method(name, value = nil, &block) ⇒ Object
Defines an “attribute” method (like
inheritance_column
ortable_name
). - #define_attribute_method(attr_name) ⇒ Object
-
#define_attribute_methods(attr_names) ⇒ Object
Declares the attributes that should be prefixed and suffixed by ActiveModel::AttributeMethods.
-
#generated_attribute_methods ⇒ Object
Returns true if the attribute methods defined have been generated.
-
#undefine_attribute_methods ⇒ Object
Removes all the previously dynamically defined methods from the class.
Instance Method Details
#alias_attribute(new_name, old_name) ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 238 def alias_attribute(new_name, old_name) attribute_method_matchers.each do |matcher| matcher_new = matcher.method_name(new_name).to_s matcher_old = matcher.method_name(old_name).to_s if matcher_new =~ COMPILABLE_REGEXP && matcher_old =~ COMPILABLE_REGEXP module_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{matcher_new}(*args) send(:#{matcher_old}, *args) end RUBY else define_method(matcher_new) do |*args| send(matcher_old, *args) end end end end |
#attribute_method_affix(*affixes) ⇒ Object
Declares a method available for all attributes with the given prefix and suffix. Uses method_missing
and respond_to?
to rewrite the method.
#{prefix}#{attr}#{suffix}(*args, &block)
to
#{prefix}attribute#{suffix}(#{attr}, *args, &block)
An #{prefix}attribute#{suffix}
instance method must exist and accept at least the attr
argument.
For example:
class Person
include ActiveModel::AttributeMethods
attr_accessor :name
attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
define_attribute_methods [:name]
private
def reset_attribute_to_default!(attr)
...
end
end
person = Person.new
person.name # => 'Gem'
person.reset_name_to_default!
person.name # => 'Gemma'
233 234 235 236 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 233 def attribute_method_affix(*affixes) self.attribute_method_matchers += affixes.map { |affix| AttributeMethodMatcher.new :prefix => affix[:prefix], :suffix => affix[:suffix] } undefine_attribute_methods end |
#attribute_method_prefix(*prefixes) ⇒ Object
Declares a method available for all attributes with the given prefix. Uses method_missing
and respond_to?
to rewrite the method.
#{prefix}#{attr}(*args, &block)
to
#{prefix}attribute(#{attr}, *args, &block)
An instance method #{prefix}attribute
must exist and accept at least the attr
argument.
For example:
class Person
include ActiveModel::AttributeMethods
attr_accessor :name
attribute_method_prefix 'clear_'
define_attribute_methods [:name]
private
def clear_attribute(attr)
send("#{attr}=", nil)
end
end
person = Person.new
person.name = "Bob"
person.name # => "Bob"
person.clear_name
person.name # => nil
158 159 160 161 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 158 def attribute_method_prefix(*prefixes) self.attribute_method_matchers += prefixes.map { |prefix| AttributeMethodMatcher.new :prefix => prefix } undefine_attribute_methods end |
#attribute_method_suffix(*suffixes) ⇒ Object
Declares a method available for all attributes with the given suffix. Uses method_missing
and respond_to?
to rewrite the method.
#{attr}#{suffix}(*args, &block)
to
attribute#{suffix}(#{attr}, *args, &block)
An attribute#{suffix}
instance method must exist and accept at least the attr
argument.
For example:
class Person
include ActiveModel::AttributeMethods
attr_accessor :name
attribute_method_suffix '_short?'
define_attribute_methods [:name]
private
def attribute_short?(attr)
send(attr).length < 5
end
end
person = Person.new
person.name = "Bob"
person.name # => "Bob"
person.name_short? # => true
195 196 197 198 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 195 def attribute_method_suffix(*suffixes) self.attribute_method_matchers += suffixes.map { |suffix| AttributeMethodMatcher.new :suffix => suffix } undefine_attribute_methods end |
#define_attr_method(name, value = nil, &block) ⇒ Object
Defines an “attribute” method (like inheritance_column
or table_name
). A new (class) method will be created with the given name. If a value is specified, the new method will return that value (as a string). Otherwise, the given block will be used to compute the value of the method.
The original method will be aliased, with the new name being prefixed with “original_”. This allows the new method to access the original value.
Example:
class Person
include ActiveModel::AttributeMethods
cattr_accessor :primary_key
cattr_accessor :inheritance_column
define_attr_method :primary_key, "sysid"
define_attr_method( :inheritance_column ) do
original_inheritance_column + "_id"
end
end
Provides you with:
Person.primary_key
# => "sysid"
Person.inheritance_column = 'address'
Person.inheritance_column
# => 'address_id'
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 100 def define_attr_method(name, value=nil, &block) sing = singleton_class sing.class_eval <<-eorb, __FILE__, __LINE__ + 1 if method_defined?('original_#{name}') undef :'original_#{name}' end alias_method :'original_#{name}', :'#{name}' eorb if block_given? sing.send :define_method, name, &block else # If we can compile the method name, do it. Otherwise use define_method. # This is an important *optimization*, please don't change it. define_method # has slower dispatch and consumes more memory. if name =~ COMPILABLE_REGEXP sing.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{name}; #{value.nil? ? 'nil' : value.to_s.inspect}; end RUBY else value = value.to_s if value sing.send(:define_method, name) { value } end end end |
#define_attribute_method(attr_name) ⇒ Object
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 285 def define_attribute_method(attr_name) attribute_method_matchers.each do |matcher| unless instance_method_already_implemented?(matcher.method_name(attr_name)) generate_method = "define_method_#{matcher.prefix}attribute#{matcher.suffix}" if respond_to?(generate_method) send(generate_method, attr_name) else method_name = matcher.method_name(attr_name) generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 if method_defined?('#{method_name}') undef :'#{method_name}' end RUBY if method_name.to_s =~ COMPILABLE_REGEXP generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{method_name}(*args) send(:#{matcher.method_missing_target}, '#{attr_name}', *args) end RUBY else generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 define_method('#{method_name}') do |*args| send('#{matcher.method_missing_target}', '#{attr_name}', *args) end RUBY end end end end end |
#define_attribute_methods(attr_names) ⇒ Object
Declares the attributes that should be prefixed and suffixed by ActiveModel::AttributeMethods.
To use, pass in an array of attribute names (as strings or symbols), be sure to declare define_attribute_methods
after you define any prefix, suffix or affix methods, or they will not hook in.
class Person
include ActiveModel::AttributeMethods
attr_accessor :name, :age, :address
attribute_method_prefix 'clear_'
# Call to define_attribute_methods must appear after the
# attribute_method_prefix, attribute_method_suffix or
# attribute_method_affix declares.
define_attribute_methods [:name, :age, :address]
private
def clear_attribute(attr)
...
end
end
281 282 283 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 281 def define_attribute_methods(attr_names) attr_names.each { |attr_name| define_attribute_method(attr_name) } end |
#generated_attribute_methods ⇒ Object
Returns true if the attribute methods defined have been generated.
327 328 329 330 331 332 333 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 327 def generated_attribute_methods #:nodoc: @generated_attribute_methods ||= begin mod = Module.new include mod mod end end |
#undefine_attribute_methods ⇒ Object
Removes all the previously dynamically defined methods from the class
320 321 322 323 324 |
# File 'activemodel/lib/active_model/attribute_methods.rb', line 320 def undefine_attribute_methods generated_attribute_methods.module_eval do instance_methods.each { |m| undef_method(m) } end end |