Module: ActiveRecord::AttributeMethods::ClassMethods

Defined in:
lib/active_record/attribute_methods.rb

Overview

Declare and check for suffixed attribute methods.

Instance Method Summary collapse

Instance Method Details

#attribute_method_suffix(*suffixes) ⇒ Object

Declare 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 < ActiveRecord::Base
  attribute_method_suffix '_changed?'

  private
    def attribute_changed?(attr)
      ...
    end
end

person = Person.find(1)
person.name_changed?    # => false
person.name = 'Hubert'
person.name_changed?    # => true


38
39
40
41
# File 'lib/active_record/attribute_methods.rb', line 38

def attribute_method_suffix(*suffixes)
  attribute_method_suffixes.concat suffixes
  rebuild_attribute_method_regexp
end

#cache_attribute?(attr_name) ⇒ Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/active_record/attribute_methods.rb', line 107

def cache_attribute?(attr_name)
  cached_attributes.include?(attr_name)
end

#cache_attributes(*attribute_names) ⇒ Object

cache_attributes allows you to declare which converted attribute values should be cached. Usually caching only pays off for attributes with expensive conversion methods, like date columns (e.g. created_at, updated_at).



97
98
99
# File 'lib/active_record/attribute_methods.rb', line 97

def cache_attributes(*attribute_names)
  attribute_names.each {|attr| cached_attributes << attr.to_s}
end

#cached_attributesObject

returns the attributes where



102
103
104
105
# File 'lib/active_record/attribute_methods.rb', line 102

def cached_attributes
  @cached_attributes ||=
    columns.select{|c| attribute_types_cached_by_default.include?(c.type)}.map(&:name).to_set
end

#define_attribute_methodsObject Also known as: define_read_methods

generates all the attribute related methods for columns in the database accessors, mutators and query methods



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/active_record/attribute_methods.rb', line 61

def define_attribute_methods
  return if generated_methods?
  columns_hash.each do |name, column|
    unless instance_method_already_implemented?(name)
      if self.serialized_attributes[name]
        define_read_method_for_serialized_attribute(name)
      else
        define_read_method(name.to_sym, name, column)
      end
    end

    unless instance_method_already_implemented?("#{name}=")
      define_write_method(name.to_sym)
    end

    unless instance_method_already_implemented?("#{name}?")
      define_question_method(name)
    end
  end
end

#generated_methodsObject

Contains the names of the generated attribute methods.



51
52
53
# File 'lib/active_record/attribute_methods.rb', line 51

def generated_methods #:nodoc:
  @generated_methods ||= Set.new
end

#generated_methods?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/active_record/attribute_methods.rb', line 55

def generated_methods?
  !generated_methods.empty?
end

#instance_method_already_implemented?(method_name) ⇒ Boolean

Check to see if the method is defined in the model or any of its subclasses that also derive from ActiveRecord. Raise DangerousAttributeError if the method is defined by ActiveRecord though.

Returns:

  • (Boolean)

Raises:



84
85
86
87
88
89
90
# File 'lib/active_record/attribute_methods.rb', line 84

def instance_method_already_implemented?(method_name)
  return true if method_name =~ /^id(=$|\?$|$)/
  @_defined_class_methods         ||= Set.new(ancestors.first(ancestors.index(ActiveRecord::Base)).collect! { |m| m.public_instance_methods(false) | m.private_instance_methods(false) | m.protected_instance_methods(false) }.flatten)
  @@_defined_activerecord_methods ||= Set.new(ActiveRecord::Base.public_instance_methods(false) | ActiveRecord::Base.private_instance_methods(false) | ActiveRecord::Base.protected_instance_methods(false))
  raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord" if @@_defined_activerecord_methods.include?(method_name)
  @_defined_class_methods.include?(method_name)
end

#match_attribute_method?(method_name) ⇒ Boolean

Returns MatchData if method_name is an attribute method.

Returns:

  • (Boolean)


44
45
46
47
# File 'lib/active_record/attribute_methods.rb', line 44

def match_attribute_method?(method_name)
  rebuild_attribute_method_regexp unless defined?(@@attribute_method_regexp) && @@attribute_method_regexp
  @@attribute_method_regexp.match(method_name)
end