Module: ActiveRecord::Persistence::ClassMethods
- Defined in:
- lib/active_record/persistence.rb
Instance Method Summary collapse
-
#_delete_record(constraints) ⇒ Object
:nodoc:.
-
#_insert_record(values) ⇒ Object
:nodoc:.
-
#_update_record(values, constraints) ⇒ Object
:nodoc:.
-
#create(attributes = nil, &block) ⇒ Object
Creates an object (or multiple objects) and saves it to the database, if validations pass.
-
#create!(attributes = nil, &block) ⇒ Object
Creates an object (or multiple objects) and saves it to the database, if validations pass.
-
#delete(id_or_array) ⇒ Object
Deletes the row with a primary key matching the
id
argument, using a SQLDELETE
statement, and returns the number of rows deleted. -
#destroy(id) ⇒ Object
Destroy an object (or multiple objects) that has the given id.
-
#instantiate(attributes, column_types = {}, &block) ⇒ Object
Given an attributes hash,
instantiate
returns a new instance of the appropriate class. -
#update(id = :all, attributes) ⇒ Object
Updates an object (or multiple objects) and saves it to the database, if validations pass.
Instance Method Details
#_delete_record(constraints) ⇒ Object
:nodoc:
200 201 202 203 204 205 206 207 208 |
# File 'lib/active_record/persistence.rb', line 200 def _delete_record(constraints) # :nodoc: constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) } dm = Arel::DeleteManager.new dm.from(arel_table) dm.wheres = constraints connection.delete(dm, "#{self} Destroy") end |
#_insert_record(values) ⇒ Object
:nodoc:
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/active_record/persistence.rb', line 168 def _insert_record(values) # :nodoc: primary_key_value = nil if primary_key && Hash === values primary_key_value = values[primary_key] if !primary_key_value && prefetch_primary_key? primary_key_value = next_sequence_value values[primary_key] = primary_key_value end end if values.empty? im = arel_table.compile_insert(connection.empty_insert_statement_value) im.into arel_table else im = arel_table.compile_insert(_substitute_values(values)) end connection.insert(im, "#{self} Create", primary_key || false, primary_key_value) end |
#_update_record(values, constraints) ⇒ Object
:nodoc:
190 191 192 193 194 195 196 197 198 |
# File 'lib/active_record/persistence.rb', line 190 def _update_record(values, constraints) # :nodoc: constraints = _substitute_values(constraints).map { |attr, bind| attr.eq(bind) } um = arel_table.where( constraints.reduce(&:and) ).compile_update(_substitute_values(values), primary_key) connection.update(um, "#{self} Update") end |
#create(attributes = nil, &block) ⇒ Object
Creates 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.
The attributes
parameter can be either a Hash or an Array of Hashes. These Hashes describe the attributes on the objects that are to be created.
Examples
# Create a single new object
User.create(first_name: 'Jamie')
# Create an Array of new objects
User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
# Create a single object and pass it into a block to set other attributes.
User.create(first_name: 'Jamie') do |u|
u.is_admin = false
end
# Creating an Array of new objects using a block, where the block is executed for each object:
User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
u.is_admin = false
end
31 32 33 34 35 36 37 38 39 |
# File 'lib/active_record/persistence.rb', line 31 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 |
#create!(attributes = nil, &block) ⇒ Object
Creates an object (or multiple objects) and saves it to the database, if validations pass. Raises a RecordInvalid error if validations fail, unlike Base#create.
The attributes
parameter can be either a Hash or an Array of Hashes. These describe which attributes to be created on the object, or multiple objects when given an Array of Hashes.
48 49 50 51 52 53 54 55 56 |
# File 'lib/active_record/persistence.rb', line 48 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 |
#delete(id_or_array) ⇒ Object
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 :dependent
association options.
You can delete multiple rows at once by passing an Array of id
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])
164 165 166 |
# File 'lib/active_record/persistence.rb', line 164 def delete(id_or_array) where(primary_key => id_or_array).delete_all end |
#destroy(id) ⇒ Object
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
- This should be the id or an array of ids to be destroyed.
Examples
# Destroy a single object
Todo.destroy(1)
# Destroy multiple objects
todos = [1,2,3]
Todo.destroy(todos)
138 139 140 141 142 143 144 |
# File 'lib/active_record/persistence.rb', line 138 def destroy(id) if id.is_a?(Array) find(id).each(&:destroy) else find(id).destroy end end |
#instantiate(attributes, column_types = {}, &block) ⇒ Object
Given an attributes hash, instantiate
returns a new instance of the appropriate class. Accepts only keys as strings.
For example, Post.all
may return Comments, Messages, and Emails by storing the record's subclass in a type
attribute. By calling instantiate
instead of new
, finder methods ensure they get new instances of the appropriate class for each record.
See ActiveRecord::Inheritance#discriminate_class_for_record
to see how this “single-table” inheritance mapping is implemented.
68 69 70 71 72 |
# File 'lib/active_record/persistence.rb', line 68 def instantiate(attributes, column_types = {}, &block) klass = discriminate_class_for_record(attributes) attributes = klass.attributes_builder.build_from_database(attributes, column_types) klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block) end |
#update(id = :all, attributes) ⇒ Object
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.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/active_record/persistence.rb', line 100 def update(id = :all, attributes) if id.is_a?(Array) 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 |