diff options
author | Jon Leighton <j@jonathanleighton.com> | 2010-11-17 11:32:31 +0000 |
---|---|---|
committer | Jon Leighton <j@jonathanleighton.com> | 2010-11-17 11:32:31 +0000 |
commit | 1bc90044b655572a4b8aa3b323905e26d37e0f2b (patch) | |
tree | 84a2d67b24e149b703308c892d1ec37a1019103b /activerecord/lib/active_record/associations | |
parent | e05162cffad7ae86615c21c6b54ab161d0261c39 (diff) | |
parent | 401c1835afb5af1a6f429061ac8484227c34909d (diff) | |
download | rails-1bc90044b655572a4b8aa3b323905e26d37e0f2b.tar.gz rails-1bc90044b655572a4b8aa3b323905e26d37e0f2b.tar.bz2 rails-1bc90044b655572a4b8aa3b323905e26d37e0f2b.zip |
Merge branch 'master' into nested_has_many_through
Conflicts:
activerecord/lib/active_record/associations/has_many_through_association.rb
activerecord/test/cases/associations/has_many_through_associations_test.rb
Diffstat (limited to 'activerecord/lib/active_record/associations')
7 files changed, 41 insertions, 46 deletions
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 896e18af01..6090376bb8 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -75,6 +75,7 @@ module ActiveRecord find(:first, *args) else load_target unless loaded? + args = args[1..-1] if args.first.kind_of?(Hash) && args.first.empty? @target.first(*args) end end @@ -120,13 +121,13 @@ module ActiveRecord # Since << flattens its argument list and inserts each record, +push+ and +concat+ behave identically. def <<(*records) result = true - load_target if @owner.new_record? + load_target unless @owner.persisted? transaction do flatten_deeper(records).each do |record| raise_on_type_mismatch(record) add_record_to_target_with_callbacks(record) do |r| - result &&= insert_record(record) unless @owner.new_record? + result &&= insert_record(record) if @owner.persisted? end end end @@ -181,7 +182,7 @@ module ActiveRecord unless options.blank? raise ArgumentError, "If finder_sql/counter_sql is used then options cannot be passed" end - + @reflection.klass.count_by_sql(custom_counter_sql) else @@ -285,12 +286,12 @@ module ActiveRecord # This method is abstract in the sense that it relies on # +count_records+, which is a method descendants have to provide. def size - if @owner.new_record? || (loaded? && !@reflection.options[:uniq]) + if !@owner.persisted? || (loaded? && !@reflection.options[:uniq]) @target.size elsif !loaded? && @reflection.options[:group] load_target.size elsif !loaded? && !@reflection.options[:uniq] && @target.is_a?(Array) - unsaved_records = @target.select { |r| r.new_record? } + unsaved_records = @target.reject { |r| r.persisted? } unsaved_records.size + count_records else count_records @@ -331,13 +332,10 @@ module ActiveRecord end def uniq(collection = self) - seen = Set.new - collection.map do |record| - unless seen.include?(record.id) - seen << record.id - record - end - end.compact + seen = {} + collection.find_all do |record| + seen[record.id] = true unless seen.key?(record.id) + end end # Replace this collection with +other_array+ @@ -357,7 +355,7 @@ module ActiveRecord def include?(record) return false unless record.is_a?(@reflection.klass) - return include_in_memory?(record) if record.new_record? + return include_in_memory?(record) unless record.persisted? load_target if @reflection.options[:finder_sql] && !loaded? return @target.include?(record) if loaded? exists?(record) @@ -372,16 +370,18 @@ module ActiveRecord end def load_target - if !@owner.new_record? || foreign_key_present + if @owner.persisted? || foreign_key_present begin - if !loaded? + unless loaded? if @target.is_a?(Array) && @target.any? @target = find_target.map do |f| i = @target.index(f) if i @target.delete_at(i).tap do |t| keys = ["id"] + t.changes.keys + (f.attribute_names - t.attribute_names) - t.attributes = f.attributes.except(*keys) + f.attributes.except(*keys).each do |k,v| + t.send("#{k}=", v) + end end else f @@ -408,11 +408,7 @@ module ActiveRecord end if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method)) - if block_given? - super { |*block_args| yield(*block_args) } - else - super - end + super elsif @reflection.klass.scopes[method] @_named_scopes_cache ||= {} @_named_scopes_cache[method] ||= {} @@ -435,10 +431,10 @@ module ActiveRecord # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */ counter_sql = @reflection.options[:finder_sql].sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" } end - + interpolate_sql(counter_sql) end - + def custom_finder_sql interpolate_sql(@reflection.options[:finder_sql]) end @@ -513,7 +509,7 @@ module ActiveRecord transaction do records.each { |record| callback(:before_remove, record) } - old_records = records.reject { |r| r.new_record? } + old_records = records.select { |r| r.persisted? } yield(records, old_records) records.each { |record| callback(:after_remove, record) } end @@ -538,14 +534,14 @@ module ActiveRecord end def ensure_owner_is_not_new - if @owner.new_record? + unless @owner.persisted? raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved" end end def fetch_first_or_last_using_find?(args) - args.first.kind_of?(Hash) || !(loaded? || @owner.new_record? || @reflection.options[:finder_sql] || - @target.any? { |record| record.new_record? } || args.first.kind_of?(Integer)) + (args.first.kind_of?(Hash) && !args.first.empty?) || !(loaded? || !@owner.persisted? || @reflection.options[:finder_sql] || + !@target.all? { |record| record.persisted? } || args.first.kind_of?(Integer)) end def include_in_memory?(record) diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index ac2aa46edf..7cd04a1ad5 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -175,10 +175,10 @@ module ActiveRecord # If the association is polymorphic the type of the owner is also set. def set_belongs_to_association_for(record) if @reflection.options[:as] - record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record? + record["#{@reflection.options[:as]}_id"] = @owner.id if @owner.persisted? record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s else - unless @owner.new_record? + if @owner.persisted? primary_key = @reflection.options[:primary_key] || :id record[@reflection.primary_key_name] = @owner.send(primary_key) end @@ -211,12 +211,12 @@ module ActiveRecord :create => construct_create_scope } end - + # Implemented by subclasses def construct_find_scope raise NotImplementedError end - + # Implemented by (some) subclasses def construct_create_scope {} @@ -252,7 +252,7 @@ module ActiveRecord def load_target return nil unless defined?(@loaded) - if !loaded? and (!@owner.new_record? || foreign_key_present) + if !loaded? and (@owner.persisted? || foreign_key_present) @target = find_target end diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 34b6cd5576..b624951cd9 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -14,7 +14,7 @@ module ActiveRecord counter_cache_name = @reflection.counter_cache_column if record.nil? - if counter_cache_name && !@owner.new_record? + if counter_cache_name && @owner.persisted? @reflection.klass.decrement_counter(counter_cache_name, previous_record_id) if @owner[@reflection.primary_key_name] end @@ -22,13 +22,13 @@ module ActiveRecord else raise_on_type_mismatch(record) - if counter_cache_name && !@owner.new_record? && record.id != @owner[@reflection.primary_key_name] + if counter_cache_name && @owner.persisted? && record.id != @owner[@reflection.primary_key_name] @reflection.klass.increment_counter(counter_cache_name, record.id) @reflection.klass.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name] end @target = (AssociationProxy === record ? record.target : record) - @owner[@reflection.primary_key_name] = record_id(record) unless record.new_record? + @owner[@reflection.primary_key_name] = record_id(record) if record.persisted? @updated = true end 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 1fc9aba5cf..da742fa668 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 @@ -34,7 +34,7 @@ module ActiveRecord end def insert_record(record, force = true, validate = true) - if record.new_record? + unless record.persisted? if force record.save! else 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 c45f2ee224..c1fc16b0ed 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -67,7 +67,7 @@ module ActiveRecord def insert_record(record, force = true, validate = true) ensure_not_nested - if record.new_record? + unless record.persisted? if force record.save! else @@ -76,8 +76,7 @@ module ActiveRecord end through_association = @owner.send(@reflection.through_reflection.name) - through_record = through_association.create!(construct_join_attributes(record)) - through_association.proxy_target << through_record + through_association.create!(construct_join_attributes(record)) end # TODO - add dependent option support diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index c6bcfec275..0ccf07f15e 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -30,18 +30,18 @@ module ActiveRecord if dependent? && !dont_save case @reflection.options[:dependent] when :delete - @target.delete unless @target.new_record? + @target.delete if @target.persisted? @owner.clear_association_cache when :destroy - @target.destroy unless @target.new_record? + @target.destroy if @target.persisted? @owner.clear_association_cache when :nullify @target[@reflection.primary_key_name] = nil - @target.save unless @owner.new_record? || @target.new_record? + @target.save if @owner.persisted? && @target.persisted? end else @target[@reflection.primary_key_name] = nil - @target.save unless @owner.new_record? || @target.new_record? + @target.save if @owner.persisted? && @target.persisted? end end @@ -56,7 +56,7 @@ module ActiveRecord set_inverse_instance(obj, @owner) @loaded = true - unless @owner.new_record? or obj.nil? or dont_save + unless !@owner.persisted? or obj.nil? or dont_save return (obj.save ? self : false) else return (obj.nil? ? nil : self) @@ -113,7 +113,7 @@ module ActiveRecord if replace_existing replace(record, true) else - record[@reflection.primary_key_name] = @owner.id unless @owner.new_record? + record[@reflection.primary_key_name] = @owner.id if @owner.persisted? self.target = record set_inverse_instance(record, @owner) end 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 e9dc32efd3..cfd4637e8e 100644 --- a/activerecord/lib/active_record/associations/has_one_through_association.rb +++ b/activerecord/lib/active_record/associations/has_one_through_association.rb @@ -23,7 +23,7 @@ module ActiveRecord if current_object new_value ? current_object.update_attributes(construct_join_attributes(new_value)) : current_object.destroy elsif new_value - if @owner.new_record? + unless @owner.persisted? self.target = new_value through_association = @owner.send(:association_instance_get, @reflection.through_reflection.name) through_association.build(construct_join_attributes(new_value)) |