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

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 < 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


46
47
48
49
# File 'lib/active_record/attribute_methods.rb', line 46

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

#cache_attribute?(attr_name) ⇒ Boolean

Returns true if the provided attribute is being cached.

Returns:

  • (Boolean)


125
126
127
# File 'lib/active_record/attribute_methods.rb', line 125

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 time related columns (e.g. created_at, updated_at).



113
114
115
# File 'lib/active_record/attribute_methods.rb', line 113

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

#cached_attributesObject

Returns the attributes which are cached. By default time related columns with datatype :datetime, :timestamp, :time, :date are cached.



119
120
121
122
# File 'lib/active_record/attribute_methods.rb', line 119

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.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/active_record/attribute_methods.rb', line 69

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)
      elsif create_time_zone_conversion_attribute?(name, column)
        define_read_method_for_time_zone_conversion(name)
      else
        define_read_method(name.to_sym, name, column)
      end
    end

    unless instance_method_already_implemented?("#{name}=")
      if create_time_zone_conversion_attribute?(name, column)
        define_write_method_for_time_zone_conversion(name)
      else  
        define_write_method(name.to_sym)
      end
    end

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

#generated_methodsObject

Contains the names of the generated attribute methods.



59
60
61
# File 'lib/active_record/attribute_methods.rb', line 59

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

#generated_methods?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/active_record/attribute_methods.rb', line 63

def generated_methods?
  !generated_methods.empty?
end

#instance_method_already_implemented?(method_name) ⇒ Boolean

Checks whether the method is defined in the model or any of its subclasses that also derive from Active Record. Raises DangerousAttributeError if the method is defined by Active Record though.

Returns:

  • (Boolean)

Raises:



99
100
101
102
103
104
105
106
# File 'lib/active_record/attribute_methods.rb', line 99

def instance_method_already_implemented?(method_name)
  method_name = method_name.to_s
  return true if method_name =~ /^id(=$|\?$|$)/
  @_defined_class_methods         ||= ancestors.first(ancestors.index(ActiveRecord::Base)).sum([]) { |m| m.public_instance_methods(false) | m.private_instance_methods(false) | m.protected_instance_methods(false) }.map(&:to_s).to_set
  @@_defined_activerecord_methods ||= (ActiveRecord::Base.public_instance_methods(false) | ActiveRecord::Base.private_instance_methods(false) | ActiveRecord::Base.protected_instance_methods(false)).map(&:to_s).to_set
  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)


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

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