Module: ActiveModel::AttributeMethods::ClassMethods
- Defined in:
- 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.
-
#attribute_methods_generated? ⇒ Boolean
Returns true if the attribute methods defined have been generated.
-
#define_attr_method(name, value = nil, &block) ⇒ Object
Defines an “attribute” method (like
inheritance_column
ortable_name
). -
#define_attribute_methods(attr_names) ⇒ Object
Declares a 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
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/active_model/attribute_methods.rb', line 233 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'
228 229 230 231 |
# File 'lib/active_model/attribute_methods.rb', line 228 def attribute_method_affix(*affixes) attribute_method_matchers.concat(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
153 154 155 156 |
# File 'lib/active_model/attribute_methods.rb', line 153 def attribute_method_prefix(*prefixes) attribute_method_matchers.concat(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
190 191 192 193 |
# File 'lib/active_model/attribute_methods.rb', line 190 def attribute_method_suffix(*suffixes) attribute_method_matchers.concat(suffixes.map { |suffix| AttributeMethodMatcher.new :suffix => suffix }) undefine_attribute_methods end |
#attribute_methods_generated? ⇒ Boolean
Returns true if the attribute methods defined have been generated.
332 333 334 |
# File 'lib/active_model/attribute_methods.rb', line 332 def attribute_methods_generated? @attribute_methods_generated ||= nil 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:
AttributePerson.primary_key
# => "sysid"
AttributePerson.inheritance_column = 'address'
AttributePerson.inheritance_column
# => 'address_id'
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/active_model/attribute_methods.rb', line 95 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_methods(attr_names) ⇒ Object
Declares a 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
276 277 278 279 280 281 282 283 284 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 |
# File 'lib/active_model/attribute_methods.rb', line 276 def define_attribute_methods(attr_names) return if attribute_methods_generated? attr_names.each do |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 @attribute_methods_generated = true end |
#generated_attribute_methods ⇒ Object
Returns true if the attribute methods defined have been generated.
323 324 325 326 327 328 329 |
# File 'lib/active_model/attribute_methods.rb', line 323 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
315 316 317 318 319 320 |
# File 'lib/active_model/attribute_methods.rb', line 315 def undefine_attribute_methods generated_attribute_methods.module_eval do instance_methods.each { |m| undef_method(m) } end @attribute_methods_generated = nil end |