Permalink
Browse files

Add explicit tests for the nested through association changes in refl…

…ection.rb
  • Loading branch information...
1 parent 1f7415a commit 82b889f7d37249adaa606558d4c05356b3e84d9a @jonleighton jonleighton committed Oct 19, 2010
@@ -450,15 +450,26 @@ def through_conditions
end
end
+ # A through association is nested iff there would be more than one join table
def nested?
- through_reflection_chain.length > 2
+ through_reflection_chain.length > 2 ||
+ through_reflection.macro == :has_and_belongs_to_many
end
# 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
- @association_primary_key ||= source_reflection.options[:primary_key] || klass.primary_key
+ @association_primary_key ||= begin
+ # Get the "actual" source reflection if the immediate source reflection has a
+ # source reflection itself
+ source_reflection = self.source_reflection
+ while source_reflection.source_reflection
+ source_reflection = source_reflection.source_reflection
+ end
+
+ source_reflection.options[:primary_key] || klass.primary_key
+ end
end
# Gets an array of possible <tt>:through</tt> source reflection names:
@@ -7,6 +7,16 @@
require 'models/ship'
require 'models/pirate'
require 'models/price_estimate'
+require 'models/essay'
+require 'models/author'
+require 'models/organization'
+require 'models/post'
+require 'models/tagging'
+require 'models/category'
+require 'models/book'
+require 'models/subscriber'
+require 'models/subscription'
+require 'models/tag'
class ReflectionTest < ActiveRecord::TestCase
include ActiveRecord::Reflection
@@ -190,6 +200,60 @@ def test_reflection_should_not_raise_error_when_compared_to_other_object
def test_has_many_through_reflection
assert_kind_of ThroughReflection, Subscriber.reflect_on_association(:books)
end
+
+ def test_through_reflection_chain
+ expected = [
+ Author.reflect_on_association(:essay_categories),
+ Author.reflect_on_association(:essays),
+ Organization.reflect_on_association(:authors)
+ ]
+ actual = Organization.reflect_on_association(:author_essay_categories).through_reflection_chain
+
+ assert_equal expected, actual
+ end
+
+ def test_through_conditions
+ expected = [
+ ["tags.name = 'Blue'"],
+ ["taggings.comment = 'first'"],
+ ["posts.title LIKE 'misc post%'"]
+ ]
+ actual = Author.reflect_on_association(:misc_post_first_blue_tags).through_conditions
+ assert_equal expected, actual
+
+ expected = [
+ ["tags.name = 'Blue'", "taggings.comment = 'first'", "posts.title LIKE 'misc post%'"],
+ [],
+ []
+ ]
+ actual = Author.reflect_on_association(:misc_post_first_blue_tags_2).through_conditions
+ assert_equal expected, actual
+ end
+
+ def test_nested?
+ assert !Author.reflect_on_association(:comments).nested?
+ assert Author.reflect_on_association(:tags).nested?
+
+ # Only goes :through once, but the through_reflection is a has_and_belongs_to_many, so this is
+ # a nested through association
+ assert Category.reflect_on_association(:post_comments).nested?
+ end
+
+ def test_association_primary_key
+ # Normal association
+ assert_equal "id", Author.reflect_on_association(:posts).association_primary_key.to_s
+ assert_equal "name", Author.reflect_on_association(:essay).association_primary_key.to_s
+
+ # Through association (uses the :primary_key option from the source reflection)
+ assert_equal "nick", Author.reflect_on_association(:subscribers).association_primary_key.to_s
+ assert_equal "name", Author.reflect_on_association(:essay_category).association_primary_key.to_s
+ assert_equal "custom_primary_key", Author.reflect_on_association(:tags_with_primary_key).association_primary_key.to_s # nested
+ end
+
+ def test_active_record_primary_key
+ assert_equal "nick", Subscriber.reflect_on_association(:subscriptions).active_record_primary_key.to_s
+ assert_equal "name", Author.reflect_on_association(:essay).active_record_primary_key.to_s
+ end
def test_collection_association
assert Pirate.reflect_on_association(:birds).collection?
@@ -90,6 +90,7 @@ def testing_proxy_target
has_many :distinct_tags, :through => :posts, :source => :tags, :select => "DISTINCT tags.*", :order => "tags.name"
has_many :post_categories, :through => :posts, :source => :categories
has_many :tagging_tags, :through => :taggings, :source => :tag
+ has_many :tags_with_primary_key, :through => :posts
has_many :books
has_many :subscriptions, :through => :books
@@ -63,6 +63,7 @@ def add_joins_and_select
has_many :misc_tags, :through => :taggings, :source => :tag, :conditions => "tags.name = 'Misc'"
has_many :funky_tags, :through => :taggings, :source => :tag
has_many :super_tags, :through => :taggings
+ has_many :tags_with_primary_key, :through => :taggings, :source => :tag_with_primary_key
has_one :tagging, :as => :taggable
has_many :first_taggings, :as => :taggable, :class_name => 'Tagging', :conditions => "taggings.comment = 'first'"
@@ -7,5 +7,6 @@ class Tagging < ActiveRecord::Base
belongs_to :super_tag, :class_name => 'Tag', :foreign_key => 'super_tag_id'
belongs_to :invalid_tag, :class_name => 'Tag', :foreign_key => 'tag_id'
belongs_to :blue_tag, :class_name => 'Tag', :foreign_key => :tag_id, :conditions => "tags.name = 'Blue'"
+ belongs_to :tag_with_primary_key, :class_name => 'Tag', :foreign_key => :tag_id, :primary_key => :custom_primary_key
belongs_to :taggable, :polymorphic => true, :counter_cache => true
end

0 comments on commit 82b889f

Please sign in to comment.