mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Place class level update
, destroy
, and delete
in Persistence::ClassMethods
The docs are obviously for class level `update`, `destroy`, and `delete`. It should be placed in `Persistence::ClassMethods` rather than `Relation`. And also, these methods are not dependent on relation. So it is not needed to delegate to `all` (plus, `klass.find` is faster than `relation.find`).
This commit is contained in:
parent
4bb4824ae7
commit
9ac7dd47c5
3 changed files with 93 additions and 95 deletions
|
@ -71,6 +71,98 @@ module ActiveRecord
|
||||||
klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block)
|
klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Updates an object (or multiple objects) and saves it to the database, if validations pass.
|
||||||
|
# The resulting object is returned whether the object was saved successfully to the database or not.
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
#
|
||||||
|
# * +id+ - This should be the id or an array of ids to be updated.
|
||||||
|
# * +attributes+ - This should be a hash of attributes or an array of hashes.
|
||||||
|
#
|
||||||
|
# ==== Examples
|
||||||
|
#
|
||||||
|
# # Updates one record
|
||||||
|
# Person.update(15, user_name: "Samuel", group: "expert")
|
||||||
|
#
|
||||||
|
# # Updates multiple records
|
||||||
|
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
|
||||||
|
# Person.update(people.keys, people.values)
|
||||||
|
#
|
||||||
|
# # Updates multiple records from the result of a relation
|
||||||
|
# people = Person.where(group: "expert")
|
||||||
|
# people.update(group: "masters")
|
||||||
|
#
|
||||||
|
# Note: Updating a large number of records will run an UPDATE
|
||||||
|
# query for each record, which may cause a performance issue.
|
||||||
|
# When running callbacks is not needed for each record update,
|
||||||
|
# it is preferred to use {update_all}[rdoc-ref:Relation#update_all]
|
||||||
|
# for updating all records in a single query.
|
||||||
|
def update(id = :all, attributes)
|
||||||
|
if id.is_a?(Array)
|
||||||
|
id.map.with_index { |one_id, idx| update(one_id, 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
|
||||||
|
|
||||||
|
# Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
|
||||||
|
# therefore all callbacks and filters are fired off before the object is deleted. This method is
|
||||||
|
# less efficient than #delete but allows cleanup methods and other actions to be run.
|
||||||
|
#
|
||||||
|
# This essentially finds the object (or multiple objects) with the given id, creates a new object
|
||||||
|
# from the attributes, and then calls destroy on it.
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
#
|
||||||
|
# * +id+ - Can be either an Integer or an Array of Integers.
|
||||||
|
#
|
||||||
|
# ==== Examples
|
||||||
|
#
|
||||||
|
# # Destroy a single object
|
||||||
|
# Todo.destroy(1)
|
||||||
|
#
|
||||||
|
# # Destroy multiple objects
|
||||||
|
# todos = [1,2,3]
|
||||||
|
# Todo.destroy(todos)
|
||||||
|
def destroy(id)
|
||||||
|
if id.is_a?(Array)
|
||||||
|
id.map { |one_id| destroy(one_id) }
|
||||||
|
else
|
||||||
|
find(id).destroy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Deletes the row with a primary key matching the +id+ argument, using a
|
||||||
|
# SQL +DELETE+ statement, and returns the number of rows deleted. Active
|
||||||
|
# Record objects are not instantiated, so the object's callbacks are not
|
||||||
|
# executed, including any <tt>:dependent</tt> association options.
|
||||||
|
#
|
||||||
|
# You can delete multiple rows at once by passing an Array of <tt>id</tt>s.
|
||||||
|
#
|
||||||
|
# Note: Although it is often much faster than the alternative, #destroy,
|
||||||
|
# skipping callbacks might bypass business logic in your application
|
||||||
|
# that ensures referential integrity or performs other essential jobs.
|
||||||
|
#
|
||||||
|
# ==== Examples
|
||||||
|
#
|
||||||
|
# # Delete a single row
|
||||||
|
# Todo.delete(1)
|
||||||
|
#
|
||||||
|
# # Delete multiple rows
|
||||||
|
# Todo.delete([2,3,4])
|
||||||
|
def delete(id_or_array)
|
||||||
|
where(primary_key => id_or_array).delete_all
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
# Called by +instantiate+ to decide which class to use for a new
|
# Called by +instantiate+ to decide which class to use for a new
|
||||||
# record instance.
|
# record instance.
|
||||||
|
|
|
@ -7,7 +7,7 @@ module ActiveRecord
|
||||||
delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
|
delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
|
||||||
delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
|
delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
|
||||||
delegate :find_by, :find_by!, to: :all
|
delegate :find_by, :find_by!, to: :all
|
||||||
delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, to: :all
|
delegate :destroy_all, :delete_all, :update_all, to: :all
|
||||||
delegate :find_each, :find_in_batches, :in_batches, to: :all
|
delegate :find_each, :find_in_batches, :in_batches, to: :all
|
||||||
delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
|
delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
|
||||||
:where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
|
:where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
|
||||||
|
|
|
@ -376,50 +376,6 @@ module ActiveRecord
|
||||||
@klass.connection.update stmt, "SQL"
|
@klass.connection.update stmt, "SQL"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Updates an object (or multiple objects) and saves it to the database, if validations pass.
|
|
||||||
# The resulting object is returned whether the object was saved successfully to the database or not.
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
#
|
|
||||||
# * +id+ - This should be the id or an array of ids to be updated.
|
|
||||||
# * +attributes+ - This should be a hash of attributes or an array of hashes.
|
|
||||||
#
|
|
||||||
# ==== Examples
|
|
||||||
#
|
|
||||||
# # Updates one record
|
|
||||||
# Person.update(15, user_name: 'Samuel', group: 'expert')
|
|
||||||
#
|
|
||||||
# # Updates multiple records
|
|
||||||
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
|
|
||||||
# Person.update(people.keys, people.values)
|
|
||||||
#
|
|
||||||
# # Updates multiple records from the result of a relation
|
|
||||||
# people = Person.where(group: 'expert')
|
|
||||||
# people.update(group: 'masters')
|
|
||||||
#
|
|
||||||
# Note: Updating a large number of records will run an
|
|
||||||
# UPDATE query for each record, which may cause a performance
|
|
||||||
# issue. When running callbacks is not needed for each record update,
|
|
||||||
# it is preferred to use #update_all for updating all records
|
|
||||||
# in a single query.
|
|
||||||
def update(id = :all, attributes)
|
|
||||||
if id.is_a?(Array)
|
|
||||||
id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) }
|
|
||||||
elsif id == :all
|
|
||||||
records.each { |record| record.update(attributes) }
|
|
||||||
else
|
|
||||||
if ActiveRecord::Base === id
|
|
||||||
raise ArgumentError, <<-MSG.squish
|
|
||||||
You are passing an instance of ActiveRecord::Base to `update`.
|
|
||||||
Please pass the id of the object by calling `.id`.
|
|
||||||
MSG
|
|
||||||
end
|
|
||||||
object = find(id)
|
|
||||||
object.update(attributes)
|
|
||||||
object
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Destroys the records by instantiating each
|
# Destroys the records by instantiating each
|
||||||
# record and calling its {#destroy}[rdoc-ref:Persistence#destroy] method.
|
# record and calling its {#destroy}[rdoc-ref:Persistence#destroy] method.
|
||||||
# Each object's callbacks are executed (including <tt>:dependent</tt> association options).
|
# Each object's callbacks are executed (including <tt>:dependent</tt> association options).
|
||||||
|
@ -440,33 +396,6 @@ module ActiveRecord
|
||||||
records.each(&:destroy).tap { reset }
|
records.each(&:destroy).tap { reset }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
|
|
||||||
# therefore all callbacks and filters are fired off before the object is deleted. This method is
|
|
||||||
# less efficient than #delete but allows cleanup methods and other actions to be run.
|
|
||||||
#
|
|
||||||
# This essentially finds the object (or multiple objects) with the given id, creates a new object
|
|
||||||
# from the attributes, and then calls destroy on it.
|
|
||||||
#
|
|
||||||
# ==== Parameters
|
|
||||||
#
|
|
||||||
# * +id+ - Can be either an Integer or an Array of Integers.
|
|
||||||
#
|
|
||||||
# ==== Examples
|
|
||||||
#
|
|
||||||
# # Destroy a single object
|
|
||||||
# Todo.destroy(1)
|
|
||||||
#
|
|
||||||
# # Destroy multiple objects
|
|
||||||
# todos = [1,2,3]
|
|
||||||
# Todo.destroy(todos)
|
|
||||||
def destroy(id)
|
|
||||||
if id.is_a?(Array)
|
|
||||||
id.map { |one_id| destroy(one_id) }
|
|
||||||
else
|
|
||||||
find(id).destroy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Deletes the records without instantiating the records
|
# Deletes the records without instantiating the records
|
||||||
# first, and hence not calling the {#destroy}[rdoc-ref:Persistence#destroy]
|
# first, and hence not calling the {#destroy}[rdoc-ref:Persistence#destroy]
|
||||||
# method nor invoking callbacks.
|
# method nor invoking callbacks.
|
||||||
|
@ -509,29 +438,6 @@ module ActiveRecord
|
||||||
affected
|
affected
|
||||||
end
|
end
|
||||||
|
|
||||||
# Deletes the row with a primary key matching the +id+ argument, using a
|
|
||||||
# SQL +DELETE+ statement, and returns the number of rows deleted. Active
|
|
||||||
# Record objects are not instantiated, so the object's callbacks are not
|
|
||||||
# executed, including any <tt>:dependent</tt> association options.
|
|
||||||
#
|
|
||||||
# You can delete multiple rows at once by passing an Array of <tt>id</tt>s.
|
|
||||||
#
|
|
||||||
# Note: Although it is often much faster than the alternative,
|
|
||||||
# #destroy, skipping callbacks might bypass business logic in
|
|
||||||
# your application that ensures referential integrity or performs other
|
|
||||||
# essential jobs.
|
|
||||||
#
|
|
||||||
# ==== Examples
|
|
||||||
#
|
|
||||||
# # Delete a single row
|
|
||||||
# Todo.delete(1)
|
|
||||||
#
|
|
||||||
# # Delete multiple rows
|
|
||||||
# Todo.delete([2,3,4])
|
|
||||||
def delete(id_or_array)
|
|
||||||
where(primary_key => id_or_array).delete_all
|
|
||||||
end
|
|
||||||
|
|
||||||
# Causes the records to be loaded from the database if they have not
|
# Causes the records to be loaded from the database if they have not
|
||||||
# been loaded already. You can use this if for some reason you need
|
# been loaded already. You can use this if for some reason you need
|
||||||
# to explicitly load some records before actually using them. The
|
# to explicitly load some records before actually using them. The
|
||||||
|
|
Loading…
Reference in a new issue