module ActiveRecord::Persistence::ClassMethods

def _delete_record(constraints) # :nodoc:

:nodoc:
def _delete_record(constraints) # :nodoc:
  constraints = constraints.map { |name, value| predicate_builder[name, value] }
  default_constraint = build_default_constraint
  constraints << default_constraint if default_constraint
  if current_scope = self.global_current_scope
    constraints << current_scope.where_clause.ast
  end
  dm = Arel::DeleteManager.new(arel_table)
  dm.wheres = constraints
  connection.delete(dm, "#{self} Destroy")
end

def _insert_record(values, returning) # :nodoc:

:nodoc:
def _insert_record(values, returning) # :nodoc:
  primary_key = self.primary_key
  primary_key_value = nil
  if prefetch_primary_key? && primary_key
    values[primary_key] ||= begin
      primary_key_value = next_sequence_value
      _default_attributes[primary_key].with_cast_value(primary_key_value)
    end
  end
  im = Arel::InsertManager.new(arel_table)
  if values.empty?
    im.insert(connection.empty_insert_statement_value(primary_key))
  else
    im.insert(values.transform_keys { |name| arel_table[name] })
  end
  connection.insert(
    im, "#{self} Create", primary_key || false, primary_key_value,
    returning: returning
  )
end

def _update_record(values, constraints) # :nodoc:

:nodoc:
def _update_record(values, constraints) # :nodoc:
  constraints = constraints.map { |name, value| predicate_builder[name, value] }
  default_constraint = build_default_constraint
  constraints << default_constraint if default_constraint
  if current_scope = self.global_current_scope
    constraints << current_scope.where_clause.ast
  end
  um = Arel::UpdateManager.new(arel_table)
  um.set(values.transform_keys { |name| arel_table[name] })
  um.wheres = constraints
  connection.update(um, "#{self} Update")
end

def build(attributes = nil, &block)

end
u.is_admin = false
User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
# Building an Array of new objects using a block, where the block is executed for each object:

end
u.is_admin = false
User.build(first_name: 'Jamie') do |u|
# Build a single object and pass it into a block to set other attributes.

User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
# Build an Array of new objects

User.build(first_name: 'Jamie')
# Build a single new object
==== Examples

attributes on the objects that are to be built.
The +attributes+ parameter can be either a Hash or an Array of Hashes. These Hashes describe the

objects.
Builds an object (or multiple objects) and returns either the built object or a list of built
def build(attributes = nil, &block)
  if attributes.is_a?(Array)
    attributes.collect { |attr| build(attr, &block) }
  else
    new(attributes, &block)
  end
end

def build_default_constraint

Skips empty scopes.
to build `where` clause from default scopes.
Called by +_update_record+ and +_delete_record+
def build_default_constraint
  return unless default_scopes?(all_queries: true)
  default_where_clause = default_scoped(all_queries: true).where_clause
  default_where_clause.ast unless default_where_clause.empty?
end

def composite_query_constraints_list # :nodoc:

:nodoc:
is for internal use when the primary key is to be treated as an array.
names is derived from +query_constraints_list+ or +primary_key+. This method
Returns an array of column names to be used in queries. The source of column
def composite_query_constraints_list # :nodoc:
  @composite_query_constraints_list ||= query_constraints_list || Array(primary_key)
end

def create(attributes = nil, &block)

end
u.is_admin = false
User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
# Creating an Array of new objects using a block, where the block is executed for each object:

end
u.is_admin = false
User.create(first_name: 'Jamie') do |u|
# Create a single object and pass it into a block to set other attributes.

User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
# Create an Array of new objects

User.create(first_name: 'Jamie')
# Create a single new object
==== Examples

attributes on the objects that are to be created.
The +attributes+ parameter can be either a Hash or an Array of Hashes. These Hashes describe the

The resulting object is returned whether the object was saved successfully to the database or not.
Creates an object (or multiple objects) and saves it to the database, if validations pass.
def create(attributes = nil, &block)
  if attributes.is_a?(Array)
    attributes.collect { |attr| create(attr, &block) }
  else
    object = new(attributes, &block)
    object.save
    object
  end
end

def create!(attributes = nil, &block)

multiple objects when given an Array of Hashes.
These describe which attributes to be created on the object, or
The +attributes+ parameter can be either a Hash or an Array of Hashes.

unlike Base#create.
if validations pass. Raises a RecordInvalid error if validations fail,
Creates an object (or multiple objects) and saves it to the database,
def create!(attributes = nil, &block)
  if attributes.is_a?(Array)
    attributes.collect { |attr| create!(attr, &block) }
  else
    object = new(attributes, &block)
    object.save!
    object
  end
end

def delete(id_or_array)

Todo.delete([2,3,4])
# Delete multiple rows

Todo.delete(1)
# Delete a single row

==== Examples

that ensures referential integrity or performs other essential jobs.
skipping callbacks might bypass business logic in your application
Note: Although it is often much faster than the alternative, #destroy,

You can delete multiple rows at once by passing an Array of ids.

executed, including any :dependent association options.
Record objects are not instantiated, so the object's callbacks are not
SQL +DELETE+ statement, and returns the number of rows deleted. Active
Deletes the row with a primary key matching the +id+ argument, using an
def delete(id_or_array)
  delete_by(primary_key => id_or_array)
end

def destroy(id)

Todo.destroy(todos)
todos = [1,2,3]
# Destroy multiple objects

Todo.destroy(1)
# Destroy a single object

==== Examples

* +id+ - This should be the id or an array of ids to be destroyed.

==== Parameters

from the attributes, and then calls destroy on it.
This essentially finds the object (or multiple objects) with the given id, creates a new object

less efficient than #delete but allows cleanup methods and other actions to be run.
therefore all callbacks and filters are fired off before the object is deleted. This method is
Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
def destroy(id)
  multiple_ids = if composite_primary_key?
    id.first.is_a?(Array)
  else
    id.is_a?(Array)
  end
  if multiple_ids
    find(id).each(&:destroy)
  else
    find(id).destroy
  end
end

def discriminate_class_for_record(record)

the single-table inheritance discriminator.
See +ActiveRecord::Inheritance#discriminate_class_for_record+ for

record instance.
Called by +instantiate+ to decide which class to use for a new
def discriminate_class_for_record(record)
  self
end

def has_query_constraints? # :nodoc:

:nodoc:
def has_query_constraints? # :nodoc:
  @has_query_constraints
end

def inherited(subclass)

def inherited(subclass)
  super
  subclass.class_eval do
    @_query_constraints_list = nil
    @has_query_constraints = false
  end
end

def insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil)

See #insert_all for documentation.

go through Active Record's type casting and serialization.
Active Record callbacks or validations. Though passed values
statement. It does not instantiate any models nor does it trigger
Inserts a single record into the database in a single SQL INSERT
def insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
  insert_all([ attributes ], returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
end

def insert!(attributes, returning: nil, record_timestamps: nil)

See #insert_all! for more.

go through Active Record's type casting and serialization.
Active Record callbacks or validations. Though passed values
statement. It does not instantiate any models nor does it trigger
Inserts a single record into the database in a single SQL INSERT
def insert!(attributes, returning: nil, record_timestamps: nil)
  insert_all!([ attributes ], returning: returning, record_timestamps: record_timestamps)
end

def insert_all(attributes, returning: nil, unique_by: nil, record_timestamps: nil)

])
{ id: 2, title: "Eloquent Ruby" }
{ id: 1, title: "Rework" },
author.books.create_with(created_at: Time.now).insert_all([

# to set default attributes for all inserted records.
# insert_all works on chained scopes, and you can use create_with

])
{ id: 1, title: "Eloquent Ruby", author: "Russ" }
{ id: 1, title: "Rework", author: "David" },
Book.insert_all([

# Here "Eloquent Ruby" is skipped because its id is not unique.
# Insert records and skip inserting any duplicates.

==== Example

Active Record's schema_cache.
:unique_by is recommended to be paired with
Because it relies on the index information from the database

record_timestamps: false # Never set timestamps automatically
record_timestamps: true # Always set timestamps automatically

way or the other, pass :record_timestamps:
To override this and force automatic setting of timestamp columns one

behavior.
the model's record_timestamps config, matching typical
By default, automatic setting of timestamp columns is controlled by
[:record_timestamps]

unique_by: :index_books_on_isbn
unique_by: %i[ author_id name ]
unique_by: :isbn

Unique indexes can be identified by columns or name:

ActiveRecord::RecordNotUnique is raised.
row has an existing id, or is not unique by another unique index,
Consider a Book model where no duplicate ISBNs make sense, but if any

To skip rows according to just one unique index pass :unique_by.

by every unique index on the table. Any duplicate rows are skipped.
(PostgreSQL and SQLite only) By default rows are considered to be unique
[:unique_by]

(for example, returning: Arel.sql("id, name as new_name")).
You can also pass an SQL string if you need more control on the return values

clause entirely.
or returning: false to omit the underlying RETURNING SQL
Pass returning: %w[ id name ] for both id and name
inserted records, which by default is the primary key.
(PostgreSQL and SQLite3 only) An array of attributes to return for all successfully
[:returning]

==== Options

:returning (see below).
Returns an ActiveRecord::Result with its contents based on

Override with :unique_by (see below).
duplicate rows are skipped.
Rows are considered to be unique by every unique index on the table. Any

the attributes for a single row and must have the same keys.
The +attributes+ parameter is an Array of Hashes. Every Hash determines

go through Active Record's type casting and serialization.
Active Record callbacks or validations. Though passed values
statement. It does not instantiate any models nor does it trigger
Inserts multiple records into the database in a single SQL INSERT
def insert_all(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
  InsertAll.new(self, attributes, on_duplicate: :skip, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps).execute
end

def insert_all!(attributes, returning: nil, record_timestamps: nil)

])
{ id: 1, title: "Eloquent Ruby", author: "Russ" }
{ id: 1, title: "Rework", author: "David" },
Book.insert_all!([
# does not have a unique id.
# Raises ActiveRecord::RecordNotUnique because "Eloquent Ruby"

])
{ title: "Eloquent Ruby", author: "Russ" }
{ title: "Rework", author: "David" },
Book.insert_all!([
# Insert multiple records

==== Examples

record_timestamps: false # Never set timestamps automatically
record_timestamps: true # Always set timestamps automatically

way or the other, pass :record_timestamps:
To override this and force automatic setting of timestamp columns one

behavior.
the model's record_timestamps config, matching typical
By default, automatic setting of timestamp columns is controlled by
[:record_timestamps]

(for example, returning: Arel.sql("id, name as new_name")).
You can also pass an SQL string if you need more control on the return values

clause entirely.
or returning: false to omit the underlying RETURNING SQL
Pass returning: %w[ id name ] for both id and name
inserted records, which by default is the primary key.
(PostgreSQL and SQLite3 only) An array of attributes to return for all successfully
[:returning]

==== Options

:returning (see below).
Returns an ActiveRecord::Result with its contents based on

To skip duplicate rows, see #insert_all. To replace them, see #upsert_all.

unique index on the table. In that case, no rows are inserted.
Raises ActiveRecord::RecordNotUnique if any rows violate a

the attributes for a single row and must have the same keys.
The +attributes+ parameter is an Array of Hashes. Every Hash determines

go through Active Record's type casting and serialization.
Active Record callbacks or validations. Though passed values
statement. It does not instantiate any models nor does it trigger
Inserts multiple records into the database in a single SQL INSERT
def insert_all!(attributes, returning: nil, record_timestamps: nil)
  InsertAll.new(self, attributes, on_duplicate: :raise, returning: returning, record_timestamps: record_timestamps).execute
end

def instantiate(attributes, column_types = {}, &block)

how this "single-table" inheritance mapping is implemented.
See ActiveRecord::Inheritance#discriminate_class_for_record to see

instances of the appropriate class for each record.
+instantiate+ instead of +new+, finder methods ensure they get new
by storing the record's subclass in a +type+ attribute. By calling
For example, +Post.all+ may return Comments, Messages, and Emails

the appropriate class. Accepts only keys as strings.
Given an attributes hash, +instantiate+ returns a new instance of
def instantiate(attributes, column_types = {}, &block)
  klass = discriminate_class_for_record(attributes)
  instantiate_instance_of(klass, attributes, column_types, &block)
end

def instantiate_instance_of(klass, attributes, column_types = {}, &block)

new instance of the class. Accepts only keys as strings.
Given a class, an attributes hash, +instantiate_instance_of+ returns a
def instantiate_instance_of(klass, attributes, column_types = {}, &block)
  attributes = klass.attributes_builder.build_from_database(attributes, column_types)
  klass.allocate.init_with_attributes(attributes, &block)
end

def query_constraints(*columns_list)

# SELECT "developers".* FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1 LIMIT 1
developer.reload

# DELETE FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
developer.delete

# DELETE FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
developer.destroy!

# UPDATE "developers" SET "name" = 'Bob' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
developer.save!
developer.name = "Bob"

# UPDATE "developers" SET "company_id" = 2 WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
developer.update!(company_id: 2)
# It is possible to update an attribute used in the query_constraints clause:

# UPDATE "developers" SET "name" = 'Nikita' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
developer.update!(name: "Nikita")

developer.inspect # => #
# SELECT "developers".* FROM "developers" ORDER BY "developers"."company_id" ASC, "developers"."id" ASC LIMIT 1
developer = Developer.first

end
query_constraints :company_id, :id
class Developer < ActiveRecord::Base

of SELECT / UPDATE / DELETE queries and in the ORDER BY clause for +#first+ and +#last+ finder methods.
Accepts a list of attribute names to be used in the WHERE clause
def query_constraints(*columns_list)
  raise ArgumentError, "You must specify at least one column to be used in querying" if columns_list.empty?
  @query_constraints_list = columns_list.map(&:to_s)
  @has_query_constraints = @query_constraints_list
end

def query_constraints_list # :nodoc:

:nodoc:
def query_constraints_list # :nodoc:
  @query_constraints_list ||= if base_class? || primary_key != base_class.primary_key
    primary_key if primary_key.is_a?(Array)
  else
    base_class.query_constraints_list
  end
end

def update(id = :all, attributes)

for updating all records in a single query.
it is preferred to use {update_all}[rdoc-ref:Relation#update_all]
When running callbacks is not needed for each record update,
query for each record, which may cause a performance issue.
Note: Updating a large number of records will run an UPDATE

people.update(group: "masters")
people = Person.where(group: "expert")
# Updates multiple records from the result of a relation

Person.update(people.keys, people.values)
people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
# Updates multiple records

Person.update(15, user_name: "Samuel", group: "expert")
# Updates one record

==== Examples

* +attributes+ - This should be a hash of attributes or an array of hashes.
Optional argument, defaults to all records in the relation.
* +id+ - This should be the id or an array of ids to be updated.

==== Parameters

The resulting object is returned whether the object was saved successfully to the database or not.
Updates an object (or multiple objects) and saves it to the database, if validations pass.
def update(id = :all, attributes)
  if id.is_a?(Array)
    if id.any?(ActiveRecord::Base)
      raise ArgumentError,
        "You are passing an array of ActiveRecord::Base instances to `update`. " \
        "Please pass the ids of the objects by calling `pluck(:id)` or `map(&:id)`."
    end
    id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
      object.update(attributes[idx])
    }
  elsif id == :all
    all.each { |record| record.update(attributes) }
  else
    if ActiveRecord::Base === id
      raise ArgumentError,
        "You are passing an instance of ActiveRecord::Base to `update`. " \
        "Please pass the id of the object by calling `.id`."
    end
    object = find(id)
    object.update(attributes)
    object
  end
end

def update!(id = :all, attributes)

of +update+, so an exception is raised if the record is invalid and saving will fail.
Updates the object (or multiple objects) just like #update but calls #update! instead
def update!(id = :all, attributes)
  if id.is_a?(Array)
    if id.any?(ActiveRecord::Base)
      raise ArgumentError,
        "You are passing an array of ActiveRecord::Base instances to `update!`. " \
        "Please pass the ids of the objects by calling `pluck(:id)` or `map(&:id)`."
    end
    id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
      object.update!(attributes[idx])
    }
  elsif id == :all
    all.each { |record| record.update!(attributes) }
  else
    if ActiveRecord::Base === id
      raise ArgumentError,
        "You are passing an instance of ActiveRecord::Base to `update!`. " \
        "Please pass the id of the object by calling `.id`."
    end
    object = find(id)
    object.update!(attributes)
    object
  end
end

def upsert(attributes, **kwargs)

See #upsert_all for documentation.

go through Active Record's type casting and serialization.
it trigger Active Record callbacks or validations. Though passed values
single SQL INSERT statement. It does not instantiate any models nor does
Updates or inserts (upserts) a single record into the database in a
def upsert(attributes, **kwargs)
  upsert_all([ attributes ], **kwargs)
end

def upsert_all(attributes, on_duplicate: :update, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)

Book.find_by(isbn: "1").title # => "Eloquent Ruby"

], unique_by: :isbn)
{ title: "Eloquent Ruby", author: "Russ", isbn: "1" }
{ title: "Rework", author: "David", isbn: "1" },
Book.upsert_all([

# Here "Eloquent Ruby" overwrites "Rework" because its ISBN is duplicate.
# Inserts multiple records, performing an upsert when records have duplicate ISBNs.

==== Examples

record_timestamps: false # Never set timestamps automatically
record_timestamps: true # Always set timestamps automatically

way or the other, pass :record_timestamps:
To override this and force automatic setting of timestamp columns one

behavior.
the model's record_timestamps config, matching typical
By default, automatic setting of timestamp columns is controlled by
[:record_timestamps]

See the related +:on_duplicate+ option. Both options can't be used at the same time.

)
update_only: [:price] # Only prices will be updated
],
{ id: 6, name: "Aluminium", price: 0.35 }
{ id: 4, name: "Gold", price: 1380.87 },
{ id: 2, name: "Copper", price: 4.84 },
[
Commodity.upsert_all(

Example:

except primary keys, read-only columns, and columns covered by the optional +unique_by+
+upsert_all+ will update all the columns that can be updated. These are all the columns
Provide a list of column names that will be updated in case of conflict. If not provided,
[:update_only]

See the related +:update_only+ option. Both options can't be used at the same time.

)
on_duplicate: Arel.sql("price = GREATEST(commodities.price, EXCLUDED.price)")
],
{ id: 6, name: "Aluminium", price: 0.35 }
{ id: 4, name: "Gold", price: 1380.87 },
{ id: 2, name: "Copper", price: 4.84 },
[
Commodity.upsert_all(

Example:

by yourself.
NOTE: If you use this option you must provide all the columns you want to update

Configure the SQL update sentence that will be used in case of conflict.
[:on_duplicate]

Active Record's schema_cache.
:unique_by is recommended to be paired with
Because it relies on the index information from the database

unique_by: :index_books_on_isbn
unique_by: %i[ author_id name ]
unique_by: :isbn

Unique indexes can be identified by columns or name:

ActiveRecord::RecordNotUnique is raised.
row has an existing id, or is not unique by another unique index,
Consider a Book model where no duplicate ISBNs make sense, but if any

To skip rows according to just one unique index pass :unique_by.

by every unique index on the table. Any duplicate rows are skipped.
(PostgreSQL and SQLite only) By default rows are considered to be unique
[:unique_by]

(for example, returning: Arel.sql("id, name as new_name")).
You can also pass an SQL string if you need more control on the return values

clause entirely.
or returning: false to omit the underlying RETURNING SQL
Pass returning: %w[ id name ] for both id and name
inserted records, which by default is the primary key.
(PostgreSQL and SQLite3 only) An array of attributes to return for all successfully
[:returning]

==== Options

columns, and columns covered by the optional +unique_by+.
there is a conflict. These are all the columns except primary keys, read-only
By default, +upsert_all+ will update all the columns that can be updated when

:returning (see below).
Returns an ActiveRecord::Result with its contents based on

the attributes for a single row and must have the same keys.
The +attributes+ parameter is an Array of Hashes. Every Hash determines

go through Active Record's type casting and serialization.
it trigger Active Record callbacks or validations. Though passed values
single SQL INSERT statement. It does not instantiate any models nor does
Updates or inserts (upserts) multiple records into the database in a
def upsert_all(attributes, on_duplicate: :update, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)
  InsertAll.new(self, attributes, on_duplicate: on_duplicate, update_only: update_only, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps).execute
end