aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2013-06-13 09:46:30 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2013-06-13 09:46:42 -0700
commitb483a0d2a75bbec2f5eee363c88238cb612f07d6 (patch)
tree40c6422cd8477ee299ace2505c9bd4258f253243
parent47e8bb10a421831f8119af91d7ca29c949268475 (diff)
downloadrails-b483a0d2a75bbec2f5eee363c88238cb612f07d6.tar.gz
rails-b483a0d2a75bbec2f5eee363c88238cb612f07d6.tar.bz2
rails-b483a0d2a75bbec2f5eee363c88238cb612f07d6.zip
Ambiguous reflections are on :through relationships are no longer supported.
For example, you need to change this: class Author < ActiveRecord::Base has_many :posts has_many :taggings, :through => :posts end class Post < ActiveRecord::Base has_one :tagging has_many :taggings end class Tagging < ActiveRecord::Base end To this: class Author < ActiveRecord::Base has_many :posts has_many :taggings, :through => :posts, :source => :tagging end class Post < ActiveRecord::Base has_one :tagging has_many :taggings end class Tagging < ActiveRecord::Base end
-rw-r--r--activerecord/CHANGELOG.md31
-rw-r--r--activerecord/lib/active_record/reflection.rb28
-rw-r--r--activerecord/test/models/author.rb2
-rw-r--r--activerecord/test/models/company.rb2
4 files changed, 60 insertions, 3 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 0955761b7f..c428522842 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,34 @@
+* Ambiguous reflections are on :through relationships are no longer supported.
+ For example, you need to change this:
+
+ class Author < ActiveRecord::Base
+ has_many :posts
+ has_many :taggings, :through => :posts
+ end
+
+ class Post < ActiveRecord::Base
+ has_one :tagging
+ has_many :taggings
+ end
+
+ class Tagging < ActiveRecord::Base
+ end
+
+ To this:
+
+ class Author < ActiveRecord::Base
+ has_many :posts
+ has_many :taggings, :through => :posts, :source => :tagging
+ end
+
+ class Post < ActiveRecord::Base
+ has_one :tagging
+ has_many :taggings
+ end
+
+ class Tagging < ActiveRecord::Base
+ end
+
* Remove column restrictions for `count`, let the database raise if the SQL is
invalid. The previous behavior was untested and surprising for the user.
Fixes #5554.
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 2aec73bd5b..dd437bd066 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -499,6 +499,11 @@ module ActiveRecord
delegate :foreign_key, :foreign_type, :association_foreign_key,
:active_record_primary_key, :type, :to => :source_reflection
+ def initialize(macro, name, scope, options, active_record)
+ super
+ @source_reflection = nil
+ end
+
# Returns the source of the through reflection. It checks both a singularized
# and pluralized form for <tt>:belongs_to</tt> or <tt>:has_many</tt>.
#
@@ -517,7 +522,28 @@ module ActiveRecord
# # => <ActiveRecord::Reflection::AssociationReflection: @macro=:belongs_to, @name=:tag, @active_record=Tagging, @plural_name="tags">
#
def source_reflection
- @source_reflection ||= source_reflection_names.collect { |name| through_reflection.klass.reflect_on_association(name) }.compact.first
+ return @source_reflection if @source_reflection
+
+ reflections = source_reflection_names.collect { |name|
+ through_reflection.klass.reflect_on_association(name)
+ }.compact
+
+ if reflections.length > 1
+ example_options = options.dup
+ example_options[:source] = source_reflection_names.first
+ ActiveSupport::Deprecation.warn <<-eowarn
+Ambiguous source reflection for through association. Please specify a :source
+directive on your declaration like:
+
+ class #{active_record.name} < ActiveRecord::Base
+ #{macro} :#{name}, #{example_options}
+ end
+
+ eowarn
+ @source_reflection = reflections.first
+ else
+ @source_reflection = reflections.first
+ end
end
# Returns the AssociationReflection object specified in the <tt>:through</tt> option
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index a96899ae10..af80b1ba42 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -85,7 +85,7 @@ class Author < ActiveRecord::Base
has_many :author_favorites
has_many :favorite_authors, -> { order('name') }, :through => :author_favorites
- has_many :taggings, :through => :posts
+ has_many :taggings, :through => :posts, :source => :taggings
has_many :taggings_2, :through => :posts, :source => :tagging
has_many :tags, :through => :posts
has_many :post_categories, :through => :posts, :source => :categories
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index dcda62e71d..b988184f34 100644
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -141,7 +141,7 @@ class Client < Company
belongs_to :firm_with_primary_key_symbols, :class_name => "Firm", :primary_key => :name, :foreign_key => :firm_name
belongs_to :readonly_firm, -> { readonly }, :class_name => "Firm", :foreign_key => "firm_id"
belongs_to :bob_firm, -> { where :name => "Bob" }, :class_name => "Firm", :foreign_key => "client_of"
- has_many :accounts, :through => :firm
+ has_many :accounts, :through => :firm, :source => :accounts
belongs_to :account
class RaisedOnSave < RuntimeError; end