diff options
Diffstat (limited to 'activerecord/lib/active_record/persistence.rb')
-rw-r--r-- | activerecord/lib/active_record/persistence.rb | 68 |
1 files changed, 54 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index b5dadb929d..09ee2ba61d 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -1,6 +1,53 @@ +require 'active_support/concern' + module ActiveRecord # = Active Record Persistence module Persistence + extend ActiveSupport::Concern + + module ClassMethods + # 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. + # + # +create+ respects mass-assignment security and accepts either +:as+ or +:without_protection+ options + # in the +options+ parameter. + # + # ==== Examples + # # Create a single new object + # User.create(:first_name => 'Jamie') + # + # # Create a single new object using the :admin mass-assignment security role + # User.create({ :first_name => 'Jamie', :is_admin => true }, :as => :admin) + # + # # Create a single new object bypassing mass-assignment security + # User.create({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true) + # + # # 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 + def create(attributes = nil, options = {}, &block) + if attributes.is_a?(Array) + attributes.collect { |attr| create(attr, options, &block) } + else + object = new(attributes, options, &block) + object.save + object + end + end + end + # Returns true if this object hasn't been saved yet -- that is, a record # for the object doesn't exist in the data store yet; otherwise, returns false. def new_record? @@ -12,8 +59,8 @@ module ActiveRecord @destroyed end - # Returns if the record is persisted, i.e. it's not a new record and it was - # not destroyed. + # Returns true if the record is persisted, i.e. it's not a new record and it was + # not destroyed, otherwise returns false. def persisted? !(new_record? || destroyed?) end @@ -114,6 +161,7 @@ module ActiveRecord became.instance_variable_set("@attributes_cache", @attributes_cache) became.instance_variable_set("@new_record", new_record?) became.instance_variable_set("@destroyed", destroyed?) + became.instance_variable_set("@errors", errors) became.type = klass.name unless self.class.descends_from_active_record? became end @@ -161,7 +209,7 @@ module ActiveRecord # The following transaction covers any possible database side-effects of the # attributes assignment. For example, setting the IDs of a child collection. with_transaction_returning_status do - self.assign_attributes(attributes, options) + assign_attributes(attributes, options) save end end @@ -172,7 +220,7 @@ module ActiveRecord # The following transaction covers any possible database side-effects of the # attributes assignment. For example, setting the IDs of a child collection. with_transaction_returning_status do - self.assign_attributes(attributes, options) + assign_attributes(attributes, options) save! end end @@ -237,7 +285,7 @@ module ActiveRecord clear_association_cache IdentityMap.without do - fresh_object = self.class.unscoped { self.class.find(self.id, options) } + fresh_object = self.class.unscoped { self.class.find(id, options) } @attributes.update(fresh_object.instance_variable_get('@attributes')) end @@ -314,19 +362,11 @@ module ActiveRecord new_id = self.class.unscoped.insert attributes_values - self.id ||= new_id if self.class.primary_key? + self.id ||= new_id if self.class.primary_key IdentityMap.add(self) if IdentityMap.enabled? @new_record = false id end - - # Initializes the attributes array with keys matching the columns from the linked table and - # the values matching the corresponding default value of that column, so - # that a new instance, or one populated from a passed-in Hash, still has all the attributes - # that instances loaded from the database would. - def attributes_from_column_definition - self.class.column_defaults.dup - end end end |