This project is archived and is in readonly mode.

#5951 ✓stale
omarqureshi

Using :joins when calling first on an association ignores joins

Reported by omarqureshi | November 11th, 2010 @ 09:34 AM | in 3.x

Running the following test:

  def test_using_joins_on_many_association_with_has_one_join
    parrot = Parrot.create!(:name => "Petal")
    pirate_with_a_ship = Pirate.create!(:catchphrase => "Where is Seaman Staines?")
    ship = Ship.create!(:name => "Black pig", :pirate => pirate_with_a_ship)
    pirate_without_a_ship = Pirate.create!(:catchphrase => "Argh, I better run from the captain!")
    parrot.pirates << pirate_without_a_ship
    parrot.pirates << pirate_with_a_ship
    assert_equal pirate_with_a_ship, parrot.pirates.all(:joins => :ship, :order => "catchphrase", :limit => 1).first
    assert_equal pirate_with_a_ship, parrot.pirates.first(:joins => :ship, :order => "catchphrase")
  end

The first query using the .all, correctly applies the :joins and :order clause, whereas the second query using .first only applies the :order.

As such, the pirate returned from the second query is the wrong pirate.

SELECT "pirates".* FROM "pirates" INNER JOIN "parrots_pirates" ON "pirates".id = "parrots_pirates".pirate_id 
INNER JOIN "ships" ON ships.pirate_id = pirates.id WHERE ("parrots_pirates".parrot_id = 1 ) 
ORDER BY catchphrase LIMIT 1
SELECT * FROM "pirates" INNER JOIN "parrots_pirates" ON "pirates".id = "parrots_pirates".pirate_id 
WHERE ("parrots_pirates".parrot_id = 1 ) ORDER BY catchphrase LIMIT 1

Is the output from debug.log showing the SQL ran by both queries.

Comments and changes to this ticket

  • Neeraj Singh

    Neeraj Singh November 15th, 2010 @ 09:26 PM

    • State changed from “new” to “open”
    • Milestone set to 3.x
    • Importance changed from “” to “Low”

    The author says that this is an issue in 2.3-stable . I can reproduce it in rails edge too.

  • Neeraj Singh

    Neeraj Singh November 16th, 2010 @ 08:31 PM

    • Assigned user set to “Aaron Patterson”
    • Tag changed from 2-3-stable, 2.3.10, activerecord, associations, first to 2-3-stable, 2.3.10, activerecord, associations, first, rails3
  • Neeraj Singh

    Neeraj Singh November 17th, 2010 @ 07:55 PM

    I spent some time (infact some good time) looking at it.

    The path followed by

    parrot.pirates.all(:joins => :ship)
    

    is

    association_collection -> method_missing

    and then call

    Pirate.with_scope(@scope) do
    args # {:joins => :capital} end

    straight forward and simple. However notice that it does select pirates.*

    In the case of

    parrot.pirates.first(:joins => :ship, :order => "catchphrase")
    

    it hits

    association_collection => first
    association_collection => find

    there method construct_find_options is called which takes the options as input. However it does not use the input and clobbers the options[:joins] and
    {:joins => :ship } is lost forever.

    The fix of that is something like this https://gist.github.com/703946 .That takes care of building the joins. However the sql produced is

    select * from pirates
    

    Any attempt to have

    select pirates.* from
    

    is making other test fail which rely on getting the join attribute . Remember we are dealing with habtm.

  • omarqureshi

    omarqureshi January 16th, 2011 @ 01:04 AM

    Sorry, have come back to this after a long hiatus.

    Isn't this what is required? The problem is the joins, not the select clause and infact, is probably preferable to have instead of table. since it is a join and a :select has not been specified.

  • rails

    rails April 19th, 2011 @ 01:00 AM

    • Tag changed from 2-3-stable, 2.3.10, activerecord, associations, first, rails3 to 2-3-stable, 2310, activerecord, associations, first, rails3

    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 April 19th, 2011 @ 01:00 AM

    • State changed from “open” to “stale”

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>

Pages