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
  with_connection do |c|
    c.delete(dm, "#{self} Destroy")
  end
end

def _insert_record(connection, values, returning) # :nodoc:

:nodoc:
def _insert_record(connection, 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
  with_connection do |c|
    c.update(um, "#{self} Update")
  end
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 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 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