module ActiveRecord::Persistence::ClassMethods
Public Instance Methods
Builds an object (or multiple objects) and returns either the built object or a list of built objects.
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 built.
Examples¶ ↑
# Build a single new object User.build(first_name: 'Jamie') # Build an Array of new objects User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) # Build a single object and pass it into a block to set other attributes. User.build(first_name: 'Jamie') do |u| u.is_admin = false end # Building an Array of new objects using a block, where the block is executed for each object: User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u| u.is_admin = false end
# File lib/active_record/persistence.rb, line 82 def build(attributes = nil, &block) if attributes.is_a?(Array) attributes.collect { |attr| build(attr, &block) } else new(attributes, &block) end end
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
# File lib/active_record/persistence.rb, line 33 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
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.
# File lib/active_record/persistence.rb, line 50 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
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.
# File lib/active_record/persistence.rb, line 100 def instantiate(attributes, column_types = {}, &block) klass = discriminate_class_for_record(attributes) instantiate_instance_of(klass, attributes, column_types, &block) end
Accepts a list of attribute names to be used in the WHERE clause of SELECT / UPDATE / DELETE queries and in the ORDER BY clause for #first
and #last
finder methods.
class Developer < ActiveRecord::Base query_constraints :company_id, :id end developer = Developer.first # SELECT "developers".* FROM "developers" ORDER BY "developers"."company_id" ASC, "developers"."id" ASC LIMIT 1 developer.inspect # => #<Developer id: 1, company_id: 1, ...> developer.update!(name: "Nikita") # UPDATE "developers" SET "name" = 'Nikita' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1 # It is possible to update an attribute used in the query_constraints clause: developer.update!(company_id: 2) # UPDATE "developers" SET "company_id" = 2 WHERE "developers"."company_id" = 1 AND "developers"."id" = 1 developer.name = "Bob" developer.save! # UPDATE "developers" SET "name" = 'Bob' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1 developer.destroy! # 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.reload # SELECT "developers".* FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1 LIMIT 1
# File lib/active_record/persistence.rb, line 212 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
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. Optional argument, defaults to all records in the relation. -
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.
# File lib/active_record/persistence.rb, line 132 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
Updates the object (or multiple objects) just like update
but calls update!
instead of update
, so an exception is raised if the record is invalid and saving will fail.
# File lib/active_record/persistence.rb, line 158 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
Private Instance Methods
Called by _update_record
and _delete_record
to build ‘where` clause from default scopes. Skips empty scopes.
# File lib/active_record/persistence.rb, line 328 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
Called by instantiate
to decide which class to use for a new record instance.
See +ActiveRecord::Inheritance#discriminate_class_for_record+ for the single-table inheritance discriminator.
# File lib/active_record/persistence.rb, line 321 def discriminate_class_for_record(record) self end
# File lib/active_record/persistence.rb, line 301 def inherited(subclass) super subclass.class_eval do @_query_constraints_list = nil @has_query_constraints = false end end
Given a class, an attributes hash, instantiate_instance_of
returns a new instance of the class. Accepts only keys as strings.
# File lib/active_record/persistence.rb, line 311 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