This project is archived and is in readonly mode.
named_scope with :joins does not work properly through HABTM associations
Reported by Alex Levy | January 5th, 2009 @ 05:17 AM | in 3.x
This is using Rails 2.2.2 on OS X Leopard.
When calling a named_scope method on an array returned via HABTM association, where the named_scope has additional :joins, the :select condition of the named_scope is ignored and the return value contains the :join'd object instead of the model object.
In an example where:
- Car has_and_belongs_to_many Parts
- Part belongs_to PartType
..if we have a named_scope :ordered defined on Part, which :joins to :part_type for part of its condition, calling @car.parts.ordered will return an array of PartTypes instead of Parts.
I've written up a more complete example and pasted it here: http://pastie.org/352661
Comments and changes to this ticket
-
Pascal Ehlert January 5th, 2009 @ 01:53 PM
I've had a quick look at this and the problem is that you have ambiguous column names and the select options from your scope are overridden by the association's select options which are constructed like this:
@reflection.options[:select] || "*"
Despite the problem with the ignored scope, what I found weird is that we are using "SELECT *" there instead of a specific select with the qualified table name.
This is apparently done to allow additional attributes on the join table to be selected as well, which I find rather confusing and which is probably a relic from those ancient "push_with_attributes" times:
def test_additional_columns_from_join_table assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date end
A first proposal of a fix would be to replace the above default SELECT statement generation by the following, which would not yet solve the scope issues but is more safe anyway:
@reflection.options[:select] || "#{@reflection.quoted_table_name}.*"
I'll see if I can work out a patch for the scope stuff while waiting for your comments.
-
Alex Levy January 6th, 2009 @ 07:37 AM
The only ambiguous column being pulled back is "id", and I think the behavior in question is precisely due to what you identified -- it's using "SELECT " instead of "SELECT parts.", and that is causing the wrong objects to come back. I'm glad you were able to pinpoint it, because I'm new to the Rails stack and was struggling to figure out where this was getting overwritten.
If I make that one change -- line 16 of has_and_belongs_to_many_association.rb -- the test shown in my pasted example will pass. That change also solves the problem I'm having in my real application, which prompted me to investigate in the first place.
So, thank you! I'm satisfied that we've resolved the issue, provided that change makes its way in.
-
Pratik March 12th, 2009 @ 03:50 PM
- State changed from new to incomplete
- Assigned user set to Pratik
Is this still a problem ? Can we please have a failing test case ?
http://guides.rails.info/contrib... should be helpful if you haven't done it before!
Thanks.
-
Alex Levy March 12th, 2009 @ 04:34 PM
I included a link to a failing test in my original report: http://pastie.org/352661
-
Pratik March 12th, 2009 @ 04:36 PM
I meant a failing test in AR test suite http://guides.rails.info/contrib...
-
Alex Levy March 13th, 2009 @ 03:37 AM
I've merged the earlier-linked failing test into the AR test suite and attached the diff here.
-
Mark Lubarsky September 11th, 2009 @ 07:33 PM
I am running into a similar issue, where my :select on the named_scope is ignored. It happens regardless of whether the main association has :select with specific fields or not. Could you please advise on whether the fix for this is coming or there is another workaround?
-
klochner February 9th, 2010 @ 07:57 PM
Ditto on having my :select ignored by named_scope in a habtm relation, e.g.,:
foo.bars.my_scope
I end up with garbage records because of column name collision on the join.
-
Tanel Suurhans March 1st, 2010 @ 03:46 PM
Seems like this bug surfaces even without :select conditions.
For example in a case like this:class Key < ActiveRecord::Base has_many :values end class Value < ActiveRecord::Base belongs_to :key default_scope :joins => :key, :order => "keys.name" end class Foo < ActiveRecord::Base has_and_belongs_to_many :values end
Now when i access Foo.first.values it will do a "SELECT *" across 2 joins which results in "keys" table id-s shadowing "values" table id-s.
SELECT * FROM "values" INNER JOIN "keys" ON "keys".id = "values".key_id INNER JOIN "foos_values" ON "values".id = "foos_values".value_id WHERE ("foos_values".foo_id = 1) ORDER BY keys.name;
Right off the bat i would say that "SELECT 'values'.*" i.e the association endpoint table name would solve this issue, although i have no idea what else would break in result of this.
-
Rudolf Gavlas April 10th, 2010 @ 03:08 AM
Since the 'default_select' method used in 'construct_finder_sql' in active_record/base.rb uses the '' as last resort, there is IMO no need to default to '' in has_and_belongs_to_many_association.rb. The attached patch fixed my problems with named_scopes and habtm associations.
-
rails February 26th, 2011 @ 12:00 AM
- Tag changed from 2.2.2, habtm, named_scope to 222, habtm, named_scope
- State changed from incomplete to open
- Importance changed from to
This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.
Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.
-
rails February 26th, 2011 @ 12:00 AM
- State changed from open to stale
-
claw March 24th, 2011 @ 11:02 PM
I appear to be hitting this issue as well in 2.3.9 on OS X Snow Leopard. I have discovered a workaround that appears to work though. Using the model names in the original report (Car HABTM Parts; Parts belongs_to PartType), you can redefine the ordered named_scope like so:
class Parts < ActiveRecord::Base has_and_belongs_to_many :cars belongs_to :part_type # Workaround for named_scope :ordered, :conditions => ..., :joins => :part_type def self.ordered scoped(:conditions => ..., :joins => :part_type) end end
This workaround appears to correctly put the table name in the SELECT query (e.g., SELECT parts.*). Looking at the named_scope code in ActiveRecord though, I don't see why scoped should behave any differently, since they both appear to ultimately end up calling ActiveRecord::NamedScope::Scope.new(self, scope, &block).
I see the milestone for this issue was moved from 2.x to 3.x; is there any chance we could see the fix for this in 2.x?
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>