Navigation Menu

Skip to content

Commit

Permalink
Allow overriding of find parameters in scoped has_many :through calls…
Browse files Browse the repository at this point in the history
… [Rick Olson]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4007 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
technoweenie committed Mar 21, 2006
1 parent c8470f8 commit 6fbf408
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 10 deletions.
14 changes: 14 additions & 0 deletions activerecord/CHANGELOG
@@ -1,5 +1,19 @@
*SVN*

* Allow overriding of find parameters in scoped has_many :through calls [Rick Olson]

In this example, :include => false disables the default eager association from loading. :select changes the standard
select clause. :joins specifies a join that is added to the end of the has_many :through query.

class Post < ActiveRecord::Base
has_many :tags, :through => :taggings, :include => :tagging do
def add_joins_and_select
find :all, :select => 'tags.*, authors.id as author_id', :include => false,
:joins => 'left outer join posts on taggings.taggable_id = posts.id left outer join authors on posts.author_id = authors.id'
end
end
end

* Fixed that schema changes while the database was open would break any connections to a SQLite database (now we reconnect if that error is throw) [DHH]

* Don't classify the has_one class when eager loading, it is already singular. Add tests. (closes #4117) [jonathan@bluewire.net.nz]
Expand Down
Expand Up @@ -24,10 +24,10 @@ def find(*args)
options[:order] = @reflection.options[:order]
end

options[:select] = construct_select
options[:from] = construct_from
options[:joins] = construct_joins
options[:include] ||= @reflection.source_reflection.options[:include]
options[:select] = construct_select(options[:select])
options[:from] ||= construct_from
options[:joins] = construct_joins(options[:joins])
options[:include] = @reflection.source_reflection.options[:include] if options[:include].nil?

merge_options_from_reflection!(options)

Expand Down Expand Up @@ -84,20 +84,20 @@ def construct_from
@reflection.table_name
end

def construct_select
selected = @reflection.options[:select] || "#{@reflection.table_name}.*"
def construct_select(custom_select = nil)
selected = custom_select || @reflection.options[:select] || "#{@reflection.table_name}.*"
end

def construct_joins
def construct_joins(custom_joins = nil)
if @reflection.through_reflection.options[:as] || @reflection.source_reflection.macro == :belongs_to
reflection_primary_key = @reflection.klass.primary_key
source_primary_key = @reflection.source_reflection.primary_key_name
else
reflection_primary_key = @reflection.source_reflection.primary_key_name
source_primary_key = @reflection.klass.primary_key
end
"INNER JOIN %s ON %s.%s = %s.%s #{@reflection.options[:joins]}" % [

"INNER JOIN %s ON %s.%s = %s.%s #{@reflection.options[:joins]} #{custom_joins}" % [
@reflection.through_reflection.table_name,
@reflection.table_name, reflection_primary_key,
@reflection.through_reflection.table_name, source_primary_key
Expand Down
11 changes: 11 additions & 0 deletions activerecord/test/associations_join_model_test.rb
Expand Up @@ -63,6 +63,17 @@ def test_polymorphic_has_many_going_through_join_model_with_include_on_source_re
end
end

def test_polymorphic_has_many_going_through_join_model_with_disabled_include
assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
assert_queries 1 do
tag.tagging
end
end

def test_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
tag.author_id
end

def test_polymorphic_has_many_going_through_join_model_with_custom_foreign_key
assert_equal tags(:misc), taggings(:welcome_general).super_tag
Expand Down
8 changes: 7 additions & 1 deletion activerecord/test/fixtures/post.rb
Expand Up @@ -21,7 +21,13 @@ def find_most_recent
has_and_belongs_to_many :special_categories, :join_table => "categories_posts", :association_foreign_key => 'category_id'

has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings, :include => :tagging
has_many :tags, :through => :taggings, :include => :tagging do
def add_joins_and_select
find :all, :select => 'tags.*, authors.id as author_id', :include => false,
:joins => 'left outer join posts on taggings.taggable_id = posts.id left outer join authors on posts.author_id = authors.id'
end
end

has_many :funky_tags, :through => :taggings, :class_name => 'Tag'
has_many :super_tags, :through => :taggings
has_one :tagging, :as => :taggable
Expand Down

0 comments on commit 6fbf408

Please sign in to comment.