This project is archived and is in readonly mode.
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 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 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 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} endstraight 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 => findthere 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 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 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 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>