Skip to content

Commit

Permalink
Add a commented, failing test for using a habtm in a has many through…
Browse files Browse the repository at this point in the history
… association. I want to refactor how aliasing works first.
  • Loading branch information
jonleighton committed Oct 12, 2010
1 parent 56064aa commit c37a5e7
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 55 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -65,52 +65,56 @@ def construct_through_joins
@reflection.through_reflection_chain.each_cons(2) do |left, right| @reflection.through_reflection_chain.each_cons(2) do |left, right|
polymorphic_join = nil polymorphic_join = nil


case if left.source_reflection.nil?
when left.source_reflection.nil? # TODO: Perhaps need to pay attention to left.options[:primary_key] and
# TODO: Perhaps need to pay attention to left.options[:primary_key] and # left.options[:foreign_key] in places here
# left.options[:foreign_key] in places here

case left.macro
case left.macro when :belongs_to
when :belongs_to left_primary_key = left.klass.primary_key
left_primary_key = left.klass.primary_key right_primary_key = left.primary_key_name
right_primary_key = left.primary_key_name when :has_many, :has_one
when :has_many, :has_one left_primary_key = left.primary_key_name
left_primary_key = left.primary_key_name right_primary_key = right.klass.primary_key
right_primary_key = right.klass.primary_key

if left.options[:as]
if left.options[:as] polymorphic_join = "AND %s.%s = %s" % [
polymorphic_join = "AND %s.%s = %s" % [ table_aliases[left], "#{left.options[:as]}_type",
table_aliases[left], "#{left.options[:as]}_type", # TODO: Why right.klass.name? Rather than left.active_record.name?
# TODO: Why right.klass.name? Rather than left.active_record.name? # TODO: Also should maybe use the base_class (see related code in JoinAssociation)
# TODO: Also should maybe use the base_class (see related code in JoinAssociation) @owner.class.quote_value(right.klass.name)
@owner.class.quote_value(right.klass.name) ]
] end
end when :has_and_belongs_to_many
when :has_and_belongs_to_many raise NotImplementedError
raise NotImplementedError end
end else
when left.source_reflection.macro == :belongs_to case left.source_reflection.macro
left_primary_key = left.klass.primary_key when :belongs_to
right_primary_key = left.source_reflection.primary_key_name left_primary_key = left.klass.primary_key

right_primary_key = left.source_reflection.primary_key_name
if left.options[:source_type]
polymorphic_join = "AND %s.%s = %s" % [ if left.options[:source_type]
table_aliases[right], polymorphic_join = "AND %s.%s = %s" % [
left.source_reflection.options[:foreign_type].to_s, table_aliases[right],
@owner.class.quote_value(left.options[:source_type]) left.source_reflection.options[:foreign_type].to_s,
] @owner.class.quote_value(left.options[:source_type])
end ]
else end
left_primary_key = left.source_reflection.primary_key_name when :has_many, :has_one
right_primary_key = right.klass.primary_key left_primary_key = left.source_reflection.primary_key_name

right_primary_key = right.klass.primary_key
if left.source_reflection.options[:as]
polymorphic_join = "AND %s.%s = %s" % [ if left.source_reflection.options[:as]
table_aliases[left], polymorphic_join = "AND %s.%s = %s" % [
"#{left.source_reflection.options[:as]}_type", table_aliases[left],
@owner.class.quote_value(right.klass.name) "#{left.source_reflection.options[:as]}_type",
] @owner.class.quote_value(right.klass.name)
end ]
end
when :has_and_belongs_to_many
raise NotImplementedError
end
end end


if right.quoted_table_name == table_aliases[right] if right.quoted_table_name == table_aliases[right]
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -713,13 +713,13 @@ def test_join_with_group
def test_find_grouped def test_find_grouped
all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories) all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories)
grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories) grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
assert_equal 4, all_posts_from_category1.size assert_equal 5, all_posts_from_category1.size
assert_equal 1, grouped_posts_of_category1.size assert_equal 2, grouped_posts_of_category1.size
end end


def test_find_scoped_grouped def test_find_scoped_grouped
assert_equal 4, categories(:general).posts_grouped_by_title.size assert_equal 5, categories(:general).posts_grouped_by_title.size
assert_equal 1, categories(:technology).posts_grouped_by_title.size assert_equal 2, categories(:technology).posts_grouped_by_title.size
end end


def test_find_scoped_grouped_having def test_find_scoped_grouped_having
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
require 'models/sponsor' require 'models/sponsor'
require 'models/club' require 'models/club'
require 'models/organization' require 'models/organization'
require 'models/category'


# NOTE: Some of these tests might not really test "nested" HMT associations, as opposed to ones which # NOTE: Some of these tests might not really test "nested" HMT associations, as opposed to ones which
# are just one level deep. But it's all the same thing really, as the "nested" code is being # are just one level deep. But it's all the same thing really, as the "nested" code is being
Expand All @@ -33,7 +34,7 @@
class NestedHasManyThroughAssociationsTest < ActiveRecord::TestCase class NestedHasManyThroughAssociationsTest < ActiveRecord::TestCase
fixtures :authors, :books, :posts, :subscriptions, :subscribers, :tags, :taggings, fixtures :authors, :books, :posts, :subscriptions, :subscribers, :tags, :taggings,
:people, :readers, :references, :jobs, :ratings, :comments, :members, :member_details, :people, :readers, :references, :jobs, :ratings, :comments, :members, :member_details,
:member_types, :sponsors, :clubs, :organizations :member_types, :sponsors, :clubs, :organizations, :categories, :categories_posts


# Through associations can either use the has_many or has_one macros. # Through associations can either use the has_many or has_one macros.
# #
Expand Down Expand Up @@ -155,9 +156,13 @@ def test_has_many_through_has_one_through_with_has_many_source_reflection
# members.first.organization_member_details_2 # members.first.organization_member_details_2
end end


# TODO: has_many through # has_many through
# Source: has_and_belongs_to_many # Source: has_and_belongs_to_many
# Through: has_many # Through: has_many
# TODO: Enable and implement this, and finish off the test
# def test_has_many_through_has_many_with_has_and_belongs_to_many_source_reflection
# assert_equal [categories(:general), categories(:technology)], authors(:bob).post_categories
# end


# TODO: has_many through # TODO: has_many through
# Source: has_many # Source: has_many
Expand Down
8 changes: 8 additions & 0 deletions activerecord/test/fixtures/categories_posts.yml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ sti_test_sti_habtm:
general_hello: general_hello:
category_id: 1 category_id: 1
post_id: 4 post_id: 4

general_misc_by_bob:
category_id: 1
post_id: 8

technology_misc_by_bob:
category_id: 2
post_id: 8
8 changes: 5 additions & 3 deletions activerecord/test/models/author.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ def testing_proxy_target
has_many :author_favorites has_many :author_favorites
has_many :favorite_authors, :through => :author_favorites, :order => 'name' has_many :favorite_authors, :through => :author_favorites, :order => 'name'


has_many :tagging, :through => :posts # through polymorphic has_one has_many :tagging, :through => :posts
has_many :taggings, :through => :posts # through polymorphic has_many has_many :taggings, :through => :posts
has_many :tags, :through => :posts # through has_many :through (on source reflection + polymorphic) has_many :tags, :through => :posts
has_many :similar_posts, :through => :tags, :source => :tagged_posts has_many :similar_posts, :through => :tags, :source => :tagged_posts
has_many :distinct_tags, :through => :posts, :source => :tags, :select => "DISTINCT tags.*", :order => "tags.name" has_many :distinct_tags, :through => :posts, :source => :tags, :select => "DISTINCT tags.*", :order => "tags.name"
has_many :post_categories, :through => :posts, :source => :categories has_many :post_categories, :through => :posts, :source => :categories
Expand All @@ -100,6 +100,8 @@ def testing_proxy_target
belongs_to :author_address, :dependent => :destroy belongs_to :author_address, :dependent => :destroy
belongs_to :author_address_extra, :dependent => :delete, :class_name => "AuthorAddress" belongs_to :author_address_extra, :dependent => :delete, :class_name => "AuthorAddress"


has_many :post_categories, :through => :posts, :source => :categories

scope :relation_include_posts, includes(:posts) scope :relation_include_posts, includes(:posts)
scope :relation_include_tags, includes(:tags) scope :relation_include_tags, includes(:tags)


Expand Down

0 comments on commit c37a5e7

Please sign in to comment.