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[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute: organization_id
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].class # => Integer
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:

:nodoc:
def _has_attribute?(attr_name) # :nodoc:
  @attributes.key?(attr_name)
end

def accessed_fields

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

# => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
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

# => ["id", "created_at", "updated_at", "name", "age"]
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?(:is_done) # => true
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

# => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22}
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)

key is to be generated (e.g. the id attribute has no value).
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)

Filters the primary keys, readonly attributes and virtual columns from the 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.

:nodoc:
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?(:nothing) # => false
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?(:nothing) # => 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