This project is archived and is in readonly mode.

#1695 ✓stale
Alex Levy

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

    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

    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

    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

    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
  • Pratik
  • Alex Levy

    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

    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?

  • marli

    marli October 15th, 2009 @ 08:30 PM

    I am also having a similar problem in rails 2.3.2 and 2.3.4

  • klochner

    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

    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

    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.

  • Jeremy Kemper

    Jeremy Kemper May 4th, 2010 @ 06:48 PM

    • Milestone changed from 2.x to 3.x
  • rails

    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

    rails February 26th, 2011 @ 12:00 AM

    • State changed from “open” to “stale”
  • claw

    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>

Attachments

Pages