module ActiveRecord::Persistence

def _create_record(attribute_names = self.attribute_names)

and returns its id.
Creates a record with values matching those of the instance attributes
def _create_record(attribute_names = self.attribute_names)
  attribute_names = attributes_for_create(attribute_names)
  new_id = self.class._insert_record(
    attributes_with_values(attribute_names)
  )
  self.id ||= new_id if @primary_key
  @new_record = false
  @previously_new_record = true
  yield(self) if block_given?
  id
end

def _delete_row

def _delete_row
  self.class._delete_record(_query_constraints_hash)
end

def _find_record(options)

def _find_record(options)
  if options && options[:lock]
    self.class.preload(strict_loaded_associations).lock(options[:lock]).find(id)
  else
    self.class.preload(strict_loaded_associations).find(id)
  end
end

def _query_constraints_hash

def _query_constraints_hash
  { @primary_key => id_in_database }
end

def _raise_readonly_record_error

def _raise_readonly_record_error
  raise ReadOnlyRecord, "#{self.class} is marked as readonly"
end

def _raise_record_not_destroyed

def _raise_record_not_destroyed
  @_association_destroy_exception ||= nil
  key = self.class.primary_key
  raise @_association_destroy_exception || RecordNotDestroyed.new("Failed to destroy #{self.class} with #{key}=#{send(key)}", self)
ensure
  @_association_destroy_exception = nil
end

def _raise_record_not_touched_error

def _raise_record_not_touched_error
  raise ActiveRecordError, <<~MSG.squish
    Cannot touch on a new or destroyed record object. Consider using
    persisted?, new_record?, or destroyed? before touching.
  MSG
end

def _touch_row(attribute_names, time)

def _touch_row(attribute_names, time)
  time ||= current_time_from_proper_timezone
  attribute_names.each do |attr_name|
    _write_attribute(attr_name, time)
  end
  _update_row(attribute_names, "touch")
end

def _update_record(attribute_names = self.attribute_names)

Returns the number of affected rows.
Updates the associated record with values matching those of the instance attributes.
def _update_record(attribute_names = self.attribute_names)
  attribute_names = attributes_for_update(attribute_names)
  if attribute_names.empty?
    affected_rows = 0
    @_trigger_update_callback = true
  else
    affected_rows = _update_row(attribute_names)
    @_trigger_update_callback = affected_rows == 1
  end
  @previously_new_record = false
  yield(self) if block_given?
  affected_rows
end

def _update_row(attribute_names, attempted_action = "update")

def _update_row(attribute_names, attempted_action = "update")
  self.class._update_record(
    attributes_with_values(attribute_names),
    _query_constraints_hash
  )
end

def apply_scoping?(options)

def apply_scoping?(options)
  !(options && options[:unscoped]) &&
    (self.class.default_scopes?(all_queries: true) || self.class.global_current_scope)
end

def becomes(klass)

If you want to change the STI column as well, use #becomes! instead.
Any change to the attributes on either instance will affect both instances.
Therefore the STI column value will still be the same.
Note: The new instance will share a link to the same attributes as the original class.

instance using the companies/company partial instead of clients/client.
like render partial: @client.becomes(Company) to render that
Action Pack to allow, say, Client < Company to do something
superclass. This can be used along with record identification in
inheritance (STI) structures where you want a subclass to appear as the
current record. This is mostly useful in relation to single table
Returns an instance of the specified +klass+ with the attributes of the
def becomes(klass)
  became = klass.allocate
  became.send(:initialize) do |becoming|
    becoming.instance_variable_set(:@attributes, @attributes)
    becoming.instance_variable_set(:@mutations_from_database, @mutations_from_database ||= nil)
    becoming.instance_variable_set(:@new_record, new_record?)
    becoming.instance_variable_set(:@destroyed, destroyed?)
    becoming.errors.copy!(errors)
  end
  became
end

def becomes!(klass)

share the same set of attributes.
Note: The old instance's STI column value will be changed too, as both objects

database.
This is especially useful if you want to persist the changed class in your
Wrapper around #becomes that also changes the instance's STI column value.
def becomes!(klass)
  became = becomes(klass)
  sti_type = nil
  if !klass.descends_from_active_record?
    sti_type = klass.sti_name
  end
  became.public_send("#{klass.inheritance_column}=", sti_type)
  became
end

def belongs_to_touch_method

+:touch+ option is used.
The name of the method used to touch a +belongs_to+ association when the
def belongs_to_touch_method
  :touch
end

def create_or_update(**, &block)

def create_or_update(**, &block)
  _raise_readonly_record_error if readonly?
  return false if destroyed?
  result = new_record? ? _create_record(&block) : _update_record(&block)
  result != false
end

def decrement(attribute, by = 1)

Only makes sense for number-based attributes. Returns +self+.
The decrement is performed directly on the underlying attribute, no setter is invoked.
Initializes +attribute+ to zero if +nil+ and subtracts the value passed as +by+ (default is 1).
def decrement(attribute, by = 1)
  increment(attribute, -by)
end

def decrement!(attribute, by = 1, touch: nil)

Returns +self+.
+update_counters+, see that for more.
Validations and callbacks are skipped. Supports the +touch+ option from
This means that any other modified attributes will still be dirty.
Only +attribute+ is updated; the record itself is not saved.
Wrapper around #decrement that writes the update to the database.
def decrement!(attribute, by = 1, touch: nil)
  increment!(attribute, -by, touch: touch)
end

def delete

options, use #destroy.
callbacks or any :dependent association
To enforce the object's +before_destroy+ and +after_destroy+

Note that this will also delete records marked as {#readonly?}[rdoc-ref:Core#readonly?].

record's primary key, and no callbacks are executed.
The row is simply removed with an SQL +DELETE+ statement on the

persisted). Returns the frozen instance.
reflect that no changes should be made (since they can't be
Deletes the record in the database and freezes this instance to
def delete
  _delete_row if persisted?
  @destroyed = true
  @previously_new_record = false
  freeze
end

def destroy

See ActiveRecord::Callbacks for further details.
and #destroy returns +false+.
before_destroy callback throws +:abort+ the action is cancelled
There's a series of callbacks associated with #destroy. If the

that no changes should be made (since they can't be persisted).
Deletes the record in the database and freezes this instance to reflect
def destroy
  _raise_readonly_record_error if readonly?
  destroy_associations
  @_trigger_destroy_callback = if persisted?
    destroy_row > 0
  else
    true
  end
  @destroyed = true
  @previously_new_record = false
  freeze
end

def destroy!

See ActiveRecord::Callbacks for further details.
and #destroy! raises ActiveRecord::RecordNotDestroyed.
before_destroy callback throws +:abort+ the action is cancelled
There's a series of callbacks associated with #destroy!. If the

that no changes should be made (since they can't be persisted).
Deletes the record in the database and freezes this instance to reflect
def destroy!
  destroy || _raise_record_not_destroyed
end

def destroy_associations

A hook to be overridden by association modules.
def destroy_associations
end

def destroy_row

def destroy_row
  _delete_row
end

def destroyed?

Returns true if this object has been destroyed, otherwise returns false.
def destroyed?
  @destroyed
end

def increment(attribute, by = 1)

Only makes sense for number-based attributes. Returns +self+.
The increment is performed directly on the underlying attribute, no setter is invoked.
Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
def increment(attribute, by = 1)
  self[attribute] ||= 0
  self[attribute] += by
  self
end

def increment!(attribute, by = 1, touch: nil)

Returns +self+.
+update_counters+, see that for more.
Validations and callbacks are skipped. Supports the +touch+ option from
This means that any other modified attributes will still be dirty.
Only +attribute+ is updated; the record itself is not saved.
Wrapper around #increment that writes the update to the database.
def increment!(attribute, by = 1, touch: nil)
  increment(attribute, by)
  change = public_send(attribute) - (public_send(:"#{attribute}_in_database") || 0)
  self.class.update_counters(id, attribute => change, touch: touch)
  public_send(:"clear_#{attribute}_change")
  self
end

def new_record?

for the object doesn't exist in the database yet; otherwise, returns false.
Returns true if this object hasn't been saved yet -- that is, a record
def new_record?
  @new_record
end

def persisted?

not destroyed, otherwise returns false.
Returns true if the record is persisted, i.e. it's not a new record and it was
def persisted?
  !(@new_record || @destroyed)
end

def previously_new_record?

returned true.
update or delete, the object didn't exist in the database and new_record? would have
Returns true if this object was just created -- that is, prior to the last
def previously_new_record?
  @previously_new_record
end

def previously_persisted?

Returns true if this object was previously persisted but now it has been deleted.
def previously_persisted?
  !new_record? && destroyed?
end

def reload(options = nil)


end
end
end
retry
else
# If the record is gone there is nothing to do.
rescue ActiveRecord::RecordNotFound
reload
# Reload lock_version in particular.
begin
rescue ActiveRecord::StaleObjectError
yield
begin
def with_optimistic_retry

Another common use case is optimistic locking handling:

assert_equal 25, account.reload.credit # check it is also persisted
assert_equal 25, account.credit # check it is updated in memory
assert account.deposit!(25)

row in the database but not the object in memory:
written to the database, or when some action modifies the corresponding
Reloading is commonly used in test suites to test something is actually

reload(lock: true) # reload with pessimistic locking

The optional :lock flag option allows you to lock the reloaded record:

returns +self+ for convenience.
is raised. Otherwise, in addition to the in-place modification the method
If the record no longer exists in the database ActiveRecord::RecordNotFound

particular the associations cache and the QueryCache.
Attributes are reloaded from the database, and caches busted, in

# => #
# Account Load (1.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT 1 [["id", 1]]
account.reload
account.id = 1
# => #
account = Account.new

manually) and modifies the receiver in-place:
This method finds the record by its primary key (which could be assigned

Reloads the record from the database.
def reload(options = nil)
  self.class.connection.clear_query_cache
  fresh_object = if apply_scoping?(options)
    _find_record(options)
  else
    self.class.unscoped { _find_record(options) }
  end
  @association_cache = fresh_object.instance_variable_get(:@association_cache)
  @attributes = fresh_object.instance_variable_get(:@attributes)
  @new_record = false
  @previously_new_record = false
  self
end

def save(**options, &block)

being updated.
Attributes marked as readonly are silently ignored if the record is

details.
#save returns +false+. See ActiveRecord::Callbacks for further
before_* callbacks throws +:abort+ the action is cancelled and
There's a series of callbacks associated with #save. If any of the

timestamps will not be updated.
the current time. However, if you supply touch: false, these
By default, #save also sets the +updated_at+/+updated_on+ attributes to

ActiveRecord::Validations for more information.
validate: false, validations are bypassed altogether. See
is cancelled and #save returns +false+, and the record won't be saved. However, if you supply
By default, save always runs validations. If any of them fail the action

the existing record gets updated.
If the model is new, a record gets created in the database, otherwise

Saves the model.

save(**options)
:call-seq:
#
def save(**options, &block)
  create_or_update(**options, &block)
rescue ActiveRecord::RecordInvalid
  false
end

def save!(**options, &block)

Unless an error is raised, returns true.

being updated.
Attributes marked as readonly are silently ignored if the record is

ActiveRecord::Callbacks for further details.
and #save! raises ActiveRecord::RecordNotSaved. See
the before_* callbacks throws +:abort+ the action is cancelled
There's a series of callbacks associated with #save!. If any of

timestamps will not be updated.
the current time. However, if you supply touch: false, these
By default, #save! also sets the +updated_at+/+updated_on+ attributes to

ActiveRecord::Validations for more information.
validate: false, validations are bypassed altogether. See
ActiveRecord::RecordInvalid gets raised, and the record won't be saved. However, if you supply
By default, #save! always runs validations. If any of them fail

the existing record gets updated.
If the model is new, a record gets created in the database, otherwise

Saves the model.

save!(**options)
:call-seq:
#
def save!(**options, &block)
  create_or_update(**options, &block) || raise(RecordNotSaved.new("Failed to save the record", self))
end

def strict_loaded_associations

def strict_loaded_associations
  @association_cache.find_all do |_, assoc|
    assoc.owner.strict_loading? && !assoc.owner.strict_loading_n_plus_one_only?
  end.map(&:first)
end

def toggle(attribute)


user.banned? # => true
user.toggle(:banned)
user.banned? # => false
user = User.first

Example:

Returns +self+.
method toggles directly the underlying value without calling any setter.
if the predicate returns +true+ the attribute will become +false+. This
Assigns to +attribute+ the boolean opposite of attribute?. So
def toggle(attribute)
  self[attribute] = !public_send("#{attribute}?")
  self
end

def toggle!(attribute)

record could be saved.
Saving is not subjected to validation checks. Returns +true+ if the
its non-bang version in the sense that it passes through the attribute setter.
Wrapper around #toggle that saves the record. This method differs from
def toggle!(attribute)
  toggle(attribute).update_attribute(attribute, self[attribute])
end

def touch(*names, time: nil)


ball.touch(:updated_at) # => raises ActiveRecordError
ball = Ball.new

ActiveRecordError will be thrown. For example:
Note that +touch+ must be used on a persisted object, or else an

@brake.touch
# triggers @brake.car.touch and @brake.car.corporation.touch

end
belongs_to :corporation, touch: true
class Car < ActiveRecord::Base

end
belongs_to :car, touch: true
class Brake < ActiveRecord::Base

then +touch+ will invoke +touch+ method on associated object.
If used along with {belongs_to}[rdoc-ref:Associations::ClassMethods#belongs_to]

product.touch(:started_at, :ended_at) # updates started_at, ended_at and updated_at/on attributes
product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
product.touch(time: Time.new(2015, 2, 16, 0, 0, 0)) # updates updated_at/on with specified time
product.touch # updates updated_at/on with current time

attributes. If no time argument is passed, the current time is used as default.
If attribute names are passed, they are updated along with updated_at/on
This method can be passed attribute names and an optional time argument.

+after_commit+ and +after_rollback+ callbacks are executed.
Please note that no validation is performed and only the +after_touch+,
or the time specified.
Saves the record with the updated_at/on attributes set to the current time
def touch(*names, time: nil)
  _raise_record_not_touched_error unless persisted?
  _raise_readonly_record_error if readonly?
  attribute_names = timestamp_attributes_for_update_in_model
  attribute_names |= names.map! do |name|
    name = name.to_s
    self.class.attribute_aliases[name] || name
  end unless names.empty?
  unless attribute_names.empty?
    affected_rows = _touch_row(attribute_names, time)
    @_trigger_update_callback = affected_rows == 1
  else
    true
  end
end

def update(attributes)

will fail and false will be returned.
record, all wrapped in a transaction. If the object is invalid, the saving
Updates the attributes of the model from the passed-in hash and saves the
def update(attributes)
  # The following transaction covers any possible database side-effects of the
  # attributes assignment. For example, setting the IDs of a child collection.
  with_transaction_returning_status do
    assign_attributes(attributes)
    save
  end
end

def update!(attributes)

of +save+, so an exception is raised if the record is invalid and saving will fail.
Updates its receiver just like #update but calls #save! instead
def update!(attributes)
  # The following transaction covers any possible database side-effects of the
  # attributes assignment. For example, setting the IDs of a child collection.
  with_transaction_returning_status do
    assign_attributes(attributes)
    save!
  end
end

def update_attribute(name, value)

Also see #update_column.

attribute is marked as readonly.
This method raises an ActiveRecord::ActiveRecordError if the

* Updates all the attributes that are dirty in this object.
* updated_at/updated_on column is updated if that column is available.
* \Callbacks are invoked.
* Validation is skipped.

This is especially useful for boolean flags on existing records. Also note that
Updates a single attribute and saves the record.
def update_attribute(name, value)
  name = name.to_s
  verify_readonly_attribute(name)
  public_send("#{name}=", value)
  save(validate: false)
end

def update_column(name, value)

Equivalent to update_columns(name => value).
def update_column(name, value)
  update_columns(name => value)
end

def update_columns(attributes)

objects, or when at least one of the attributes is marked as readonly.
This method raises an ActiveRecord::ActiveRecordError when called on new

* However, attributes are serialized with the same rules as ActiveRecord::Relation#update_all
* +updated_at+/+updated_on+ are not updated.
* \Callbacks are skipped.
* \Validations are skipped.

procedures are totally bypassed. In particular:
the database, but take into account that in consequence the regular update
This is the fastest way to update attributes because it goes straight to

user.update_columns(last_request_at: Time.current)

statement and sets them in the receiver:
Updates the attributes directly in the database issuing an UPDATE SQL
def update_columns(attributes)
  raise ActiveRecordError, "cannot update a new record" if new_record?
  raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
  _raise_readonly_record_error if readonly?
  attributes = attributes.transform_keys do |key|
    name = key.to_s
    name = self.class.attribute_aliases[name] || name
    verify_readonly_attribute(name) || name
  end
  update_constraints = _query_constraints_hash
  attributes = attributes.each_with_object({}) do |(k, v), h|
    h[k] = @attributes.write_cast_value(k, v)
    clear_attribute_change(k)
  end
  affected_rows = self.class._update_record(
    attributes,
    update_constraints
  )
  affected_rows == 1
end

def verify_readonly_attribute(name)

def verify_readonly_attribute(name)
  raise ActiveRecordError, "#{name} is marked as readonly" if self.class.readonly_attribute?(name)
end