diff options
author | Jon Leighton <j@jonathanleighton.com> | 2011-10-05 20:20:04 +0100 |
---|---|---|
committer | Jon Leighton <j@jonathanleighton.com> | 2011-10-05 20:21:21 +0100 |
commit | 2e9e647fee59d975c9564d96c924d29ffe57f2a2 (patch) | |
tree | ed70277b1e139e88a63a05b967f36e9eb433d4b0 /activerecord/lib | |
parent | 64747654ca661d695622c0ad9e33b8d9e6df8048 (diff) | |
download | rails-2e9e647fee59d975c9564d96c924d29ffe57f2a2.tar.gz rails-2e9e647fee59d975c9564d96c924d29ffe57f2a2.tar.bz2 rails-2e9e647fee59d975c9564d96c924d29ffe57f2a2.zip |
Raise an exception on unknown primary key inside AssociationReflection.
An association between two models cannot be made if a relevant key is
unknown, so fail fast rather than generating invalid SQL. Fixes #3207.
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/errors.rb | 13 | ||||
-rw-r--r-- | activerecord/lib/active_record/reflection.rb | 12 |
2 files changed, 21 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb index ad7d8cd63c..96870cb338 100644 --- a/activerecord/lib/active_record/errors.rb +++ b/activerecord/lib/active_record/errors.rb @@ -169,4 +169,17 @@ module ActiveRecord @errors = errors end end + + # Raised when a primary key is needed, but there is not one specified in the schema or model. + class UnknownPrimaryKey < ActiveRecordError + attr_reader :model + + def initialize(model) + @model = model + end + + def message + "Unknown primary key for table #{model.table_name} in model #{model}." + end + end end diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 120ff0cac6..5285060288 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -213,11 +213,11 @@ module ActiveRecord # klass option is necessary to support loading polymorphic associations def association_primary_key(klass = nil) - options[:primary_key] || (klass || self.klass).primary_key + options[:primary_key] || primary_key(klass || self.klass) end def active_record_primary_key - @active_record_primary_key ||= options[:primary_key] || active_record.primary_key + @active_record_primary_key ||= options[:primary_key] || primary_key(active_record) end def counter_cache_column @@ -357,6 +357,10 @@ module ActiveRecord active_record.name.foreign_key end end + + def primary_key(klass) + klass.primary_key || raise(UnknownPrimaryKey.new(klass)) + end end # Holds all the meta-data about a :through association as it was specified @@ -461,7 +465,7 @@ module ActiveRecord # We want to use the klass from this reflection, rather than just delegate straight to # the source_reflection, because the source_reflection may be polymorphic. We still # need to respect the source_reflection's :primary_key option, though. - def association_primary_key(klass = self.klass) + def association_primary_key(klass = nil) # Get the "actual" source reflection if the immediate source reflection has a # source reflection itself source_reflection = self.source_reflection @@ -469,7 +473,7 @@ module ActiveRecord source_reflection = source_reflection.source_reflection end - source_reflection.options[:primary_key] || klass.primary_key + source_reflection.options[:primary_key] || primary_key(klass || self.klass) end # Gets an array of possible <tt>:through</tt> source reflection names: |