aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/persistence.rb
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2017-09-11 09:41:08 +0900
committerRyuta Kamizono <kamipo@gmail.com>2017-09-18 08:12:59 +0900
commit9ac7dd47c5e847f7dbfb8d527ee2b917fa9fcd38 (patch)
tree272f5872138b5dbc41ffd7ea641e3c8721aad4dc /activerecord/lib/active_record/persistence.rb
parent4bb4824ae711b7b550e8e33b428110575adaefac (diff)
downloadrails-9ac7dd47c5e847f7dbfb8d527ee2b917fa9fcd38.tar.gz
rails-9ac7dd47c5e847f7dbfb8d527ee2b917fa9fcd38.tar.bz2
rails-9ac7dd47c5e847f7dbfb8d527ee2b917fa9fcd38.zip
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`).
Diffstat (limited to 'activerecord/lib/active_record/persistence.rb')
-rw-r--r--activerecord/lib/active_record/persistence.rb92
1 files changed, 92 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index fbbf9082cc..4a5ccdc597 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -71,6 +71,98 @@ module ActiveRecord
klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block)
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
# Called by +instantiate+ to decide which class to use for a new
# record instance.