aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations.rb
diff options
context:
space:
mode:
authorMikel Lindsaar <raasdnil@gmail.com>2009-11-24 21:45:14 +1100
committerMikel Lindsaar <raasdnil@gmail.com>2009-11-24 21:45:14 +1100
commit5f2395041d1578433fa825ed5c6f26a201f2203d (patch)
tree3b78531ae77a2173ad0df1103543bdfea0b1f60f /activerecord/lib/active_record/associations.rb
parent3a72923e27195983d37bdb39ef26b29cf03d3483 (diff)
parente62e6d409986cd5c99234689aa49e3162d7b3a59 (diff)
downloadrails-5f2395041d1578433fa825ed5c6f26a201f2203d.tar.gz
rails-5f2395041d1578433fa825ed5c6f26a201f2203d.tar.bz2
rails-5f2395041d1578433fa825ed5c6f26a201f2203d.zip
Merge branch 'master' of git://github.com/rails/rails into rails_master
Diffstat (limited to 'activerecord/lib/active_record/associations.rb')
-rwxr-xr-xactiverecord/lib/active_record/associations.rb33
1 files changed, 23 insertions, 10 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 03c8d4b3ed..0fcd288fc5 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/enumerable'
module ActiveRecord
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
@@ -60,6 +61,12 @@ module ActiveRecord
end
end
+ class HasAndBelongsToManyAssociationWithPrimaryKeyError < ActiveRecordError #:nodoc:
+ def initialize(reflection)
+ super("Primary key is not allowed in a has_and_belongs_to_many join table (#{reflection.options[:join_table]}).")
+ end
+ end
+
class HasAndBelongsToManyAssociationForeignKeyNeeded < ActiveRecordError #:nodoc:
def initialize(reflection)
super("Cannot create self referential has_and_belongs_to_many association on '#{reflection.class_name rescue nil}##{reflection.name rescue nil}'. :association_foreign_key cannot be the same as the :foreign_key.")
@@ -1396,8 +1403,8 @@ module ActiveRecord
end
define_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
- ids = (new_value || []).reject { |nid| nid.blank? }
- send("#{reflection.name}=", reflection.klass.find(ids))
+ ids = (new_value || []).reject { |nid| nid.blank? }.map(&:to_i)
+ send("#{reflection.name}=", reflection.klass.find(ids).index_by(&:id).values_at(*ids))
end
end
end
@@ -1480,7 +1487,7 @@ module ActiveRecord
if reflection.options.include?(:dependent)
# Add polymorphic type if the :as option is present
dependent_conditions = []
- dependent_conditions << "#{reflection.primary_key_name} = \#{record.quoted_id}"
+ dependent_conditions << "#{reflection.primary_key_name} = \#{record.#{reflection.name}.send(:owner_quoted_id)}"
dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as]
dependent_conditions << sanitize_sql(reflection.options[:conditions], reflection.quoted_table_name) if reflection.options[:conditions]
dependent_conditions << extra_conditions if extra_conditions
@@ -1674,7 +1681,6 @@ module ActiveRecord
def create_has_and_belongs_to_many_reflection(association_id, options, &extension)
options.assert_valid_keys(valid_keys_for_has_and_belongs_to_many_association)
-
options[:extend] = create_extension_modules(association_id, extension, options[:extend])
reflection = create_reflection(:has_and_belongs_to_many, association_id, options, self)
@@ -1684,6 +1690,9 @@ module ActiveRecord
end
reflection.options[:join_table] ||= join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(reflection.class_name))
+ if connection.supports_primary_key? && (connection.primary_key(reflection.options[:join_table]) rescue false)
+ raise HasAndBelongsToManyAssociationWithPrimaryKeyError.new(reflection)
+ end
reflection
end
@@ -1922,12 +1931,16 @@ module ActiveRecord
reflection = base.reflections[name]
is_collection = [:has_many, :has_and_belongs_to_many].include?(reflection.macro)
- parent_records = records.map do |record|
- descendant = record.send(reflection.name)
- next unless descendant
- descendant.target.uniq! if is_collection
- descendant
- end.flatten.compact
+ parent_records = []
+ records.each do |record|
+ if descendant = record.send(reflection.name)
+ if is_collection
+ parent_records.concat descendant.target.uniq
+ else
+ parent_records << descendant
+ end
+ end
+ end
remove_duplicate_results!(reflection.klass, parent_records, associations[name]) unless parent_records.empty?
end