Module: ActiveRecord::AttributeMethods
| Relationships & Source Files | |
| Namespace Children | |
|
Modules:
| |
|
Classes:
| |
| Extension / Inclusion / Inheritance Descendants | |
|
Included In:
| |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
|
|
|
Instance Chain:
|
|
| Defined in: | activerecord/lib/active_record/attribute_methods.rb, activerecord/lib/active_record.rb, activerecord/lib/active_record/attribute_methods/before_type_cast.rb, activerecord/lib/active_record/attribute_methods/composite_primary_key.rb, activerecord/lib/active_record/attribute_methods/dirty.rb, activerecord/lib/active_record/attribute_methods/primary_key.rb, activerecord/lib/active_record/attribute_methods/query.rb, activerecord/lib/active_record/attribute_methods/read.rb, activerecord/lib/active_record/attribute_methods/serialization.rb, activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb, activerecord/lib/active_record/attribute_methods/write.rb |
Overview
===============================
Constant Summary
-
RESTRICTED_CLASS_METHODS =
# File 'activerecord/lib/active_record/attribute_methods.rb', line 37%w(private public protected allocate new name superclass).freeze
::ActiveModel::AttributeMethods - Included
::ActiveModel::AttributeMethods - Attributes & Methods
- .attribute_aliases rw
- #attribute_aliases readonly
- .attribute_aliases? ⇒ Boolean rw
- #attribute_aliases? ⇒ Boolean readonly
- .attribute_method_patterns rw
- #attribute_method_patterns readonly
- .attribute_method_patterns? ⇒ Boolean rw
- #attribute_method_patterns? ⇒ Boolean readonly
Class Method Summary
- .dangerous_attribute_methods Internal use only
::ActiveSupport::Concern - Extended
| class_methods | Define class methods from given block. |
| included | Evaluate given block in context of base class, so that you can write class macros here. |
| prepended | Evaluate given block in context of base class, so that you can write class macros here. |
| append_features, prepend_features | |
::ActiveSupport::Autoload - Extended
Instance Method Summary
-
#[](attr_name)
Returns the value of the attribute identified by
attr_nameafter it has been type cast. -
#[]=(attr_name, value)
Updates the attribute identified by
attr_nameusing the specifiedvalue. -
#accessed_fields
Returns the name of all database fields which have been read from this model.
-
#attribute_for_inspect(attr_name)
Returns an
#inspect-like string for the value of the attributeattr_name. -
#attribute_names
Returns an array of names for the attributes available on this object.
-
#attribute_present?(attr_name) ⇒ Boolean
Returns
trueif the specifiedattributehas been set by the user or by a database load and is neithernilnorempty?(the latter only applies to objects that respond toempty?, most notably Strings). -
#attributes
Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
-
#has_attribute?(attr_name) ⇒ Boolean
Returns
trueif the given attribute is in the attributes hash, otherwisefalse. -
#respond_to?(name, include_private = false) ⇒ Boolean
A Person object with a name attribute can ask
person.respond_to?(:name),person.respond_to?(:name=), andperson.respond_to?(:name?)which will all returntrue. - #attribute_method?(attr_name) ⇒ Boolean private
-
#attributes_for_create(attribute_names)
private
Filters out the virtual columns and also primary keys, from the attribute names, when the primary key is to be generated (e.g.
-
#attributes_for_update(attribute_names)
private
Filters the primary keys, readonly attributes and virtual columns from the attribute names.
- #attributes_with_values(attribute_names) private
- #format_for_inspect(name, value) private
- #pk_attribute?(name) ⇒ Boolean private
- #_has_attribute?(attr_name) ⇒ Boolean Internal use only
-
#resolve_alias(attr_name)
Internal use only
This gets overridden on models that use attribute aliases.
::ActiveModel::AttributeMethods - Included
| #attribute_missing |
|
| #method_missing | Allows access to the object attributes, which are held in the hash returned by #attributes, as though they were first-class methods. |
| #respond_to? | A |
| #respond_to_without_attributes? | Checks whether the object responds to |
| #_read_attribute, #attribute_method?, | |
| #matched_attribute_method | Returns a struct representing the matching attribute method. |
| #missing_attribute | |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class ActiveModel::AttributeMethods
DSL Calls
included
[ GitHub ]12 13 14 15 16 17 18 19 20 21 22
# File 'activerecord/lib/active_record/attribute_methods.rb', line 12
included do initialize_generated_modules include Read include Write include BeforeTypeCast include Query include PrimaryKey include TimeZoneConversion include Dirty include Serialization end
Class Attribute Details
.attribute_aliases (rw)
[ GitHub ]# File 'activemodel/lib/active_model/attribute_methods.rb', line 64
class_attribute :attribute_aliases, instance_writer: false, default: {}.freeze
.attribute_aliases? ⇒ Boolean (rw)
[ GitHub ]
# File 'activemodel/lib/active_model/attribute_methods.rb', line 64
class_attribute :attribute_aliases, instance_writer: false, default: {}.freeze
.attribute_method_patterns (rw)
[ GitHub ]# File 'activemodel/lib/active_model/attribute_methods.rb', line 66
class_attribute :attribute_method_patterns, instance_writer: false, default: ClassMethods::AttributeMethodPatternSet.new([ ClassMethods::AttributeMethodPattern::BASE ])
.attribute_method_patterns? ⇒ Boolean (rw)
[ GitHub ]
# File 'activemodel/lib/active_model/attribute_methods.rb', line 66
class_attribute :attribute_method_patterns, instance_writer: false, default: ClassMethods::AttributeMethodPatternSet.new([ ClassMethods::AttributeMethodPattern::BASE ])
Class Method Details
.dangerous_attribute_methods
# File 'activerecord/lib/active_record/attribute_methods.rb', line 44
def dangerous_attribute_methods # :nodoc: @dangerous_attribute_methods ||= ( Base.instance_methods + Base.private_instance_methods - Base.superclass.instance_methods - Base.superclass.private_instance_methods + %i[__id__ dup freeze frozen? hash class clone] ).map { |m| -m.to_s }.to_set.freeze end
Instance Attribute Details
#attribute_aliases (readonly)
[ GitHub ]# File 'activemodel/lib/active_model/attribute_methods.rb', line 64
class_attribute :attribute_aliases, instance_writer: false, default: {}.freeze
#attribute_aliases? ⇒ Boolean (readonly)
[ GitHub ]
# File 'activemodel/lib/active_model/attribute_methods.rb', line 64
class_attribute :attribute_aliases, instance_writer: false, default: {}.freeze
#attribute_method_patterns (readonly)
[ GitHub ]# File 'activemodel/lib/active_model/attribute_methods.rb', line 66
class_attribute :attribute_method_patterns, instance_writer: false, default: ClassMethods::AttributeMethodPatternSet.new([ ClassMethods::AttributeMethodPattern::BASE ])
#attribute_method_patterns? ⇒ Boolean (readonly)
[ GitHub ]
# File 'activemodel/lib/active_model/attribute_methods.rb', line 66
class_attribute :attribute_method_patterns, instance_writer: false, default: ClassMethods::AttributeMethodPatternSet.new([ ClassMethods::AttributeMethodPattern::BASE ])
Instance Method Details
#[](attr_name)
Returns the value of the attribute identified by attr_name after it has
been type cast. (For information about specific type casting behavior, see
the types under ::ActiveModel::Type.)
class Person < {ActiveRecord::Base}
belongs_to :organization
end
person = {Person.new}(name: "Francesco", date_of_birth: "2004-12-12")
person[:name] # => "Francesco"
person[:date_of_birth] # => {Date.new}(2004, 12, 12)
person[:organization_id] # => nil
Raises ::ActiveModel::MissingAttributeError if the attribute is missing.
Note, however, that the id attribute will never be considered missing.
person = {Person.select}(:name).first
person[:name] # => "Francesco"
person[:date_of_birth] # => {ActiveModel::MissingAttributeError}: missing attribute 'date_of_birth' for Person
person[:organization_id] # => {ActiveModel::MissingAttributeError}: missing attribute 'organization_id' for Person
person[:id] # => nil
# File 'activerecord/lib/active_record/attribute_methods.rb', line 474
def [](attr_name) read_attribute(attr_name) { |n| missing_attribute(n, caller) } end
#[]=(attr_name, value)
Updates the attribute identified by attr_name using the specified
value. The attribute value will be type cast upon being read.
class Person < {ActiveRecord::Base}
end
person = {Person.new}
person[:date_of_birth] = "2004-12-12"
person[:date_of_birth] # => {Date.new}(2004, 12, 12)
# File 'activerecord/lib/active_record/attribute_methods.rb', line 489
def []=(attr_name, value) write_attribute(attr_name, value) end
#_has_attribute?(attr_name) ⇒ Boolean
# File 'activerecord/lib/active_record/attribute_methods.rb', line 371
def _has_attribute?(attr_name) # :nodoc: @attributes.key?(attr_name) end
#accessed_fields
Returns the name of all database fields which have been read from this model. This can be useful in development mode to determine which fields need to be selected. For performance critical pages, selecting only the required fields can be an easy performance win (assuming you aren't using all of the fields on the model).
For example:
class PostsController < {ActionController::Base}
after_action :print_accessed_fields, only: :index
def index
@posts = Post.all
end
private
def print_accessed_fields
p @posts.first.accessed_fields
end
end
Which allows you to quickly change your code to:
class PostsController < {ActionController::Base}
def index
@posts = Post.select(:id, :title, :, :updated_at)
end
end
# File 'activerecord/lib/active_record/attribute_methods.rb', line 525
def accessed_fields @attributes.accessed end
#attribute_for_inspect(attr_name)
Returns an #inspect-like string for the value of the
attribute attr_name. ::String attributes are truncated up to 50
characters. Other attributes return the value of #inspect
without modification.
person = {Person.create!}(name: 'David Heinemeier Hansson ' * 3)
person.attribute_for_inspect(:name)
#### => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
person.attribute_for_inspect(:created_at)
#### => "\"2012-10-22 00:15:07.000000000 +0000\""
person.attribute_for_inspect(:tag_ids)
#### => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
# File 'activerecord/lib/active_record/attribute_methods.rb', line 420
def attribute_for_inspect(attr_name) attr_name = attr_name.is_a?(Symbol) ? attr_name.name : attr_name.to_s attr_name = self.class.attribute_aliases[attr_name] || attr_name value = _read_attribute(attr_name) format_for_inspect(attr_name, value) end
#attribute_method?(attr_name) ⇒ Boolean (private)
# File 'activerecord/lib/active_record/attribute_methods.rb', line 530
def attribute_method?(attr_name) @attributes&.key?(attr_name) end
#attribute_names
Returns an array of names for the attributes available on this object.
class Person < {ActiveRecord::Base}
end
person = {Person.new}
person.attribute_names
#### => ["id", "created_at", "updated_at", "name", "age"]
# File 'activerecord/lib/active_record/attribute_methods.rb', line 385
def attribute_names @attributes.keys end
#attribute_present?(attr_name) ⇒ Boolean
Returns true if the specified attribute has been set by the user or by a
database load and is neither nil nor empty? (the latter only applies
to objects that respond to empty?, most notably Strings). Otherwise, false.
Note that it always returns true with boolean attributes.
class Task < {ActiveRecord::Base}
end
task = {Task.new}(title: '', is_done: false)
task.attribute_present?(:title) # => false
task.attribute_present?(:is_done) # => true
task.title = 'Buy milk'
task.is_done = true
task.attribute_present?(:title) # => true
task.attribute_present?(:is_done) # => true
# File 'activerecord/lib/active_record/attribute_methods.rb', line 444
def attribute_present?(attr_name) value = read_attribute(attr_name) !value.nil? && !(value.respond_to?(:empty?) && value.empty?) end
#attributes
Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
class Person < {ActiveRecord::Base}
end
person = {Person.create}(name: 'Francesco', age: 22)
person.attributes
#### => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22}
# File 'activerecord/lib/active_record/attribute_methods.rb', line 399
def attributes @attributes.to_hash end
#attributes_for_create(attribute_names) (private)
Filters out the virtual columns and also primary keys, from the attribute names, when the primary key is to be generated (e.g. the id attribute has no value).
# File 'activerecord/lib/active_record/attribute_methods.rb', line 550
def attributes_for_create(attribute_names) attribute_names &= self.class.column_names attribute_names.delete_if do |name| (pk_attribute?(name) && id.nil?) || column_for_attribute(name).virtual? end end
#attributes_for_update(attribute_names) (private)
Filters the primary keys, readonly attributes and virtual columns from the attribute names.
# File 'activerecord/lib/active_record/attribute_methods.rb', line 539
def attributes_for_update(attribute_names) attribute_names &= self.class.column_names attribute_names.delete_if do |name| self.class.readonly_attribute?(name) || self.class.counter_cache_column?(name) || column_for_attribute(name).virtual? end end
#attributes_with_values(attribute_names) (private)
[ GitHub ]# File 'activerecord/lib/active_record/attribute_methods.rb', line 534
def attributes_with_values(attribute_names) attribute_names.index_with { |name| @attributes[name] } end
#format_for_inspect(name, value) (private)
[ GitHub ]# File 'activerecord/lib/active_record/attribute_methods.rb', line 558
def format_for_inspect(name, value) if value.nil? value.inspect else inspected_value = if value.is_a?(String) && value.length > 50 "#{value[0, 50]}...".inspect elsif value.is_a?(Date) || value.is_a?(Time) %("#{value.to_fs(:inspect)}") else value.inspect end inspection_filter.filter_param(name, inspected_value) end end
#has_attribute?(attr_name) ⇒ Boolean
Returns true if the given attribute is in the attributes hash, otherwise false.
class Person < {ActiveRecord::Base}
alias_attribute :new_name, :name
end
person = {Person.new}
person.has_attribute?(:name) # => true
person.has_attribute?(:new_name) # => true
person.has_attribute?('age') # => true
person.has_attribute?(:nothing) # => false
# File 'activerecord/lib/active_record/attribute_methods.rb', line 366
def has_attribute?(attr_name) attr_name = resolve_alias(attr_name.is_a?(Symbol) ? attr_name.name : attr_name.to_s) @attributes.key?(attr_name) end
#pk_attribute?(name) ⇒ Boolean (private)
# File 'activerecord/lib/active_record/attribute_methods.rb', line 574
def pk_attribute?(name) name == @primary_key end
#resolve_alias(attr_name)
This gets overridden on models that use attribute aliases. Internal, don't call it!
# File 'activerecord/lib/active_record/attribute_methods.rb', line 26
def resolve_alias(attr_name) # :nodoc: attr_name end
#respond_to?(name, include_private = false) ⇒ Boolean
A Person object with a name attribute can ask person.respond_to?(:name),
person.respond_to?(:name=), and person.respond_to?(:name?)
which will all return true. It also defines the attribute methods if they have
not been generated.
class Person < {ActiveRecord::Base}
end
person = {Person.new}
person.respond_to?(:name) # => true
person.respond_to?(:name=) # => true
person.respond_to?(:name?) # => true
person.respond_to?('age') # => true
person.respond_to?('age=') # => true
person.respond_to?('age?') # => true
person.respond_to?(:nothing) # => false
# File 'activerecord/lib/active_record/attribute_methods.rb', line 340
def respond_to?(name, include_private = false) return false unless super # If the result is true then check for the select case. # For queries selecting a subset of columns, return false for unselected columns. if @attributes name = name.name if name.is_a?(Symbol) return _has_attribute?(name) if self.class.columns_hash.key?(name) end true end