module ActiveRecord::AttributeMethods
Experimental RBS support (using type sampling data from the type_fusion
project).
# sig/active_record.rbs module ActiveRecord::AttributeMethods def dangerous_attribute_methods: () -> untyped end
def [](attr_name)
person[:name] # => ActiveModel::MissingAttributeError: missing attribute: name
person = Person.select('id').first
person[:age] # => 22
person[:name] # => "Francesco"
person = Person.new(name: 'Francesco', age: '22')
end
belongs_to :organization
class Person < ActiveRecord::Base
Note: +:id+ is always present.
ActiveModel::MissingAttributeError if the identified attribute is missing.
"2004-12-12" in a date column is cast to a date object, like Date.new(2004, 12, 12)). It raises
Returns the value of the attribute identified by attr_name after it has been typecast (for example,
def [](attr_name) read_attribute(attr_name) { |n| missing_attribute(n, caller) } end
def []=(attr_name, value)
person[:age] # => 22
person[:age] = '22'
person = Person.new
end
class Person < ActiveRecord::Base
(Alias for the protected #write_attribute method).
Updates the attribute identified by attr_name with the specified +value+.
def []=(attr_name, value) write_attribute(attr_name, value) end
def _has_attribute?(attr_name) # :nodoc:
def _has_attribute?(attr_name) # :nodoc: @attributes.key?(attr_name) end
def accessed_fields
end
@posts = Post.select(:id, :title, :author_id, :updated_at)
def index
class PostsController < ActionController::Base
Which allows you to quickly change your code to:
end
end
p @posts.first.accessed_fields
def print_accessed_fields
private
end
@posts = Post.all
def index
after_action :print_accessed_fields, only: :index
class PostsController < ActionController::Base
For example:
all of the fields on the model).
required fields can be an easy performance win (assuming you aren't using
need to be selected. For performance critical pages, selecting only the
model. This can be useful in development mode to determine which fields
Returns the name of all database fields which have been read from this
def accessed_fields @attributes.accessed end
def attribute_for_inspect(attr_name)
person.attribute_for_inspect(:tag_ids)
# => "\"2012-10-22 00:15:07.000000000 +0000\""
person.attribute_for_inspect(:created_at)
# => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
person.attribute_for_inspect(:name)
person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
without modification.
characters. Other attributes return the value of #inspect
attribute +attr_name+. String attributes are truncated up to 50
Returns an #inspect-like string for the value of the
def attribute_for_inspect(attr_name) attr_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
def attribute_method?(attr_name)
def attribute_method?(attr_name) # We check defined? because Syck calls respond_to? before actually calling initialize. defined?(@attributes) && @attributes.key?(attr_name) end
def attribute_names
person.attribute_names
person = Person.new
end
class Person < ActiveRecord::Base
Returns an array of names for the attributes available on this object.
def attribute_names @attributes.keys end
def attribute_present?(attr_name)
task.attribute_present?(:title) # => true
task.is_done = true
task.title = 'Buy milk'
task.attribute_present?(:is_done) # => true
task.attribute_present?(:title) # => false
task = Task.new(title: '', is_done: false)
end
class Task < ActiveRecord::Base
Note that it always returns +true+ with boolean attributes.
to objects that respond to empty?, most notably Strings). Otherwise, +false+.
database load and is neither +nil+ nor empty? (the latter only applies
Returns +true+ if the specified +attribute+ has been set by the user or by a
def attribute_present?(attr_name) attr_name = attr_name.to_s attr_name = self.class.attribute_aliases[attr_name] || attr_name value = _read_attribute(attr_name) !value.nil? && !(value.respond_to?(:empty?) && value.empty?) end
def attributes
person.attributes
person = Person.create(name: 'Francesco', age: 22)
end
class Person < ActiveRecord::Base
Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
def attributes @attributes.to_hash end
def attributes_for_create(attribute_names)
Filters out the virtual columns and also primary keys, from the attribute names, when the primary
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
def attributes_for_update(attribute_names)
def attributes_for_update(attribute_names) attribute_names &= self.class.column_names attribute_names.delete_if do |name| self.class.readonly_attribute?(name) || column_for_attribute(name).virtual? end end
def attributes_with_values(attribute_names)
def attributes_with_values(attribute_names) attribute_names.index_with { |name| @attributes[name] } end
def dangerous_attribute_methods # :nodoc:
Experimental RBS support (using type sampling data from the type_fusion
project).
def dangerous_attribute_methods: () -> untyped
This signature was generated using 10 samples from 1 application.
def dangerous_attribute_methods # :nodoc: @dangerous_attribute_methods ||= ( Base.instance_methods + Base.private_instance_methods - Base.superclass.instance_methods - Base.superclass.private_instance_methods ).map { |m| -m.to_s }.to_set.freeze end
def format_for_inspect(name, value)
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
def has_attribute?(attr_name)
person.has_attribute?('age') # => true
person.has_attribute?(:new_name) # => true
person.has_attribute?(:name) # => true
person = Person.new
end
alias_attribute :new_name, :name
class Person < ActiveRecord::Base
Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
def has_attribute?(attr_name) attr_name = attr_name.to_s attr_name = self.class.attribute_aliases[attr_name] || attr_name @attributes.key?(attr_name) end
def pk_attribute?(name)
def pk_attribute?(name) name == @primary_key end
def respond_to?(name, include_private = false)
person.respond_to?('age?') # => true
person.respond_to?('age=') # => true
person.respond_to?('age') # => true
person.respond_to?(:name?) # => true
person.respond_to?(:name=) # => true
person.respond_to?(:name) # => true
person = Person.new
end
class Person < ActiveRecord::Base
not been generated.
which will all return +true+. It also defines the attribute methods if they have
person.respond_to?(:name=), and person.respond_to?(:name?)
A Person object with a name attribute can ask person.respond_to?(:name),
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. # We check defined?(@attributes) not to issue warnings if called on objects that # have been allocated but not yet initialized. if defined?(@attributes) if name = self.class.symbol_column_to_string(name.to_sym) return _has_attribute?(name) end end true end