diff options
Diffstat (limited to 'activerecord/lib/active_record/associations')
10 files changed, 41 insertions, 10 deletions
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index d9903243ce..ddf4ce4058 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -3,6 +3,8 @@ require 'active_support/core_ext/array/wrap' module ActiveRecord module Associations + # = Active Record Association Collection + # # AssociationCollection is an abstract class that provides common stuff to # ease the implementation of association proxies that represent # collections. See the class hierarchy in AssociationProxy. @@ -24,10 +26,10 @@ module ActiveRecord delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped - def select(select = nil, &block) + def select(select = nil) if block_given? load_target - @target.select(&block) + @target.select.each { |e| yield e } else scoped.select(select) end @@ -121,7 +123,7 @@ module ActiveRecord end end - # Add +records+ to this association. Returns +self+ so method calls may be chained. + # Add +records+ to this association. Returns +self+ so method calls may be chained. # Since << flattens its argument list and inserts each record, +push+ and +concat+ behave identically. def <<(*records) result = true @@ -166,7 +168,7 @@ module ActiveRecord reset_target! reset_named_scopes_cache! end - + # Calculate sum using SQL, not Enumerable def sum(*args) if block_given? @@ -239,7 +241,7 @@ module ActiveRecord if @reflection.options[:dependent] && @reflection.options[:dependent] == :destroy destroy_all - else + else delete_all end @@ -388,7 +390,11 @@ module ActiveRecord begin if !loaded? if @target.is_a?(Array) && @target.any? - @target = find_target + @target.find_all {|t| t.new_record? } + @target = find_target.map do |f| + i = @target.index(f) + t = @target.delete_at(i) if i + (t && t.changed?) ? t : f + end + @target else @target = find_target end @@ -403,6 +409,17 @@ module ActiveRecord end def method_missing(method, *args) + case method.to_s + when 'find_or_create' + return find(:first, :conditions => args.first) || create(args.first) + when /^find_or_create_by_(.*)$/ + rest = $1 + return send("find_by_#{rest}", *args) || + method_missing("create_by_#{rest}", *args) + when /^create_by_(.*)$/ + return create Hash[$1.split('_and_').zip(args)] + end + if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method)) if block_given? super { |*block_args| yield(*block_args) } @@ -514,8 +531,8 @@ module ActiveRecord def callbacks_for(callback_name) full_callback_name = "#{callback_name}_for_#{@reflection.name}" @owner.class.read_inheritable_attribute(full_callback_name.to_sym) || [] - end - + end + def ensure_owner_is_not_new if @owner.new_record? raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved" diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index e88618d278..f333f4d603 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -2,6 +2,8 @@ require 'active_support/core_ext/array/wrap' module ActiveRecord module Associations + # = Active Record Associations + # # This is the root class of all association proxies: # # AssociationProxy diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index d2f2267e5c..c2a6495db5 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -1,4 +1,5 @@ module ActiveRecord + # = Active Record Belongs To Associations module Associations class BelongsToAssociation < AssociationProxy #:nodoc: def create(attributes = {}) diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb index f6edd6383c..38454ec242 100644 --- a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb @@ -1,4 +1,5 @@ module ActiveRecord + # = Active Record Belongs To Polymorphic Association module Associations class BelongsToPolymorphicAssociation < AssociationProxy #:nodoc: def replace(record) diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index 7f39a189e4..c989c3536d 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -1,4 +1,5 @@ module ActiveRecord + # = Active Record Has And Belongs To Many Association module Associations class HasAndBelongsToManyAssociation < AssociationCollection #:nodoc: def create(attributes = {}) diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 0464e8ceea..d74fb7c702 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -1,4 +1,5 @@ module ActiveRecord + # = Active Record Has Many Association module Associations # This is the proxy that handles a has many association. # @@ -109,7 +110,11 @@ module ActiveRecord create_scoping = {} set_belongs_to_association_for(create_scoping) { - :find => { :conditions => @finder_sql, :readonly => false, :order => @reflection.options[:order], :limit => @reflection.options[:limit], :include => @reflection.options[:include]}, + :find => { :conditions => @finder_sql, + :readonly => false, + :order => @reflection.options[:order], + :limit => @reflection.options[:limit], + :include => @reflection.options[:include]}, :create => create_scoping } end diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 5338bb099d..17f850756f 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -2,6 +2,7 @@ require "active_record/associations/through_association_scope" require 'active_support/core_ext/object/blank' module ActiveRecord + # = Active Record Has Many Through Association module Associations class HasManyThroughAssociation < HasManyAssociation #:nodoc: include ThroughAssociationScope diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index ea769fd48b..68b8b792ad 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -1,4 +1,5 @@ module ActiveRecord + # = Active Record Belongs To Has One Association module Associations class HasOneAssociation < AssociationProxy #:nodoc: def initialize(owner, reflection) diff --git a/activerecord/lib/active_record/associations/has_one_through_association.rb b/activerecord/lib/active_record/associations/has_one_through_association.rb index a79bf943d1..fba0a2bfcc 100644 --- a/activerecord/lib/active_record/associations/has_one_through_association.rb +++ b/activerecord/lib/active_record/associations/has_one_through_association.rb @@ -1,6 +1,7 @@ require "active_record/associations/through_association_scope" module ActiveRecord + # = Active Record Has One Through Association module Associations class HasOneThroughAssociation < HasOneAssociation include ThroughAssociationScope diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index 1d2f323112..22e1033a9d 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -1,4 +1,5 @@ module ActiveRecord + # = Active Record Through Association Scope module Associations module ThroughAssociationScope @@ -91,7 +92,7 @@ module ActiveRecord # Construct attributes for :through pointing to owner and associate. def construct_join_attributes(associate) - # TODO: revist this to allow it for deletion, supposing dependent option is supported + # TODO: revisit this to allow it for deletion, supposing dependent option is supported raise ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(@owner, @reflection) if [:has_one, :has_many].include?(@reflection.source_reflection.macro) join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id) |