Skip to content

Commit b483a0d

Browse files
committed
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
1 parent 47e8bb1 commit b483a0d

File tree

4 files changed

+60
-3
lines changed

4 files changed

+60
-3
lines changed

activerecord/CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
* Ambiguous reflections are on :through relationships are no longer supported.
2+
For example, you need to change this:
3+
4+
class Author < ActiveRecord::Base
5+
has_many :posts
6+
has_many :taggings, :through => :posts
7+
end
8+
9+
class Post < ActiveRecord::Base
10+
has_one :tagging
11+
has_many :taggings
12+
end
13+
14+
class Tagging < ActiveRecord::Base
15+
end
16+
17+
To this:
18+
19+
class Author < ActiveRecord::Base
20+
has_many :posts
21+
has_many :taggings, :through => :posts, :source => :tagging
22+
end
23+
24+
class Post < ActiveRecord::Base
25+
has_one :tagging
26+
has_many :taggings
27+
end
28+
29+
class Tagging < ActiveRecord::Base
30+
end
31+
132
* Remove column restrictions for `count`, let the database raise if the SQL is
233
invalid. The previous behavior was untested and surprising for the user.
334
Fixes #5554.

activerecord/lib/active_record/reflection.rb

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,11 @@ class ThroughReflection < AssociationReflection #:nodoc:
499499
delegate :foreign_key, :foreign_type, :association_foreign_key,
500500
:active_record_primary_key, :type, :to => :source_reflection
501501

502+
def initialize(macro, name, scope, options, active_record)
503+
super
504+
@source_reflection = nil
505+
end
506+
502507
# Returns the source of the through reflection. It checks both a singularized
503508
# and pluralized form for <tt>:belongs_to</tt> or <tt>:has_many</tt>.
504509
#
@@ -517,7 +522,28 @@ class ThroughReflection < AssociationReflection #:nodoc:
517522
# # => <ActiveRecord::Reflection::AssociationReflection: @macro=:belongs_to, @name=:tag, @active_record=Tagging, @plural_name="tags">
518523
#
519524
def source_reflection
520-
@source_reflection ||= source_reflection_names.collect { |name| through_reflection.klass.reflect_on_association(name) }.compact.first
525+
return @source_reflection if @source_reflection
526+
527+
reflections = source_reflection_names.collect { |name|
528+
through_reflection.klass.reflect_on_association(name)
529+
}.compact
530+
531+
if reflections.length > 1
532+
example_options = options.dup
533+
example_options[:source] = source_reflection_names.first
534+
ActiveSupport::Deprecation.warn <<-eowarn
535+
Ambiguous source reflection for through association. Please specify a :source
536+
directive on your declaration like:
537+
538+
class #{active_record.name} < ActiveRecord::Base
539+
#{macro} :#{name}, #{example_options}
540+
end
541+
542+
eowarn
543+
@source_reflection = reflections.first
544+
else
545+
@source_reflection = reflections.first
546+
end
521547
end
522548

523549
# Returns the AssociationReflection object specified in the <tt>:through</tt> option

activerecord/test/models/author.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class Author < ActiveRecord::Base
8585
has_many :author_favorites
8686
has_many :favorite_authors, -> { order('name') }, :through => :author_favorites
8787

88-
has_many :taggings, :through => :posts
88+
has_many :taggings, :through => :posts, :source => :taggings
8989
has_many :taggings_2, :through => :posts, :source => :tagging
9090
has_many :tags, :through => :posts
9191
has_many :post_categories, :through => :posts, :source => :categories

activerecord/test/models/company.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class Client < Company
141141
belongs_to :firm_with_primary_key_symbols, :class_name => "Firm", :primary_key => :name, :foreign_key => :firm_name
142142
belongs_to :readonly_firm, -> { readonly }, :class_name => "Firm", :foreign_key => "firm_id"
143143
belongs_to :bob_firm, -> { where :name => "Bob" }, :class_name => "Firm", :foreign_key => "client_of"
144-
has_many :accounts, :through => :firm
144+
has_many :accounts, :through => :firm, :source => :accounts
145145
belongs_to :account
146146

147147
class RaisedOnSave < RuntimeError; end

0 commit comments

Comments
 (0)