Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange behavior with references(:foo) on a query #26290

Closed
duffyjp opened this issue Aug 26, 2016 · 2 comments
Closed

Strange behavior with references(:foo) on a query #26290

duffyjp opened this issue Aug 26, 2016 · 2 comments

Comments

@duffyjp
Copy link
Contributor

duffyjp commented Aug 26, 2016

Steps to reproduce

Test case here: https://gist.github.com/duffyjp/80e1d10a6a5f329baefc3a3865e058a0

$ ruby references_bug.rb 

  1) Failure:
BugTest#test_references [references_bug.rb:62]:
Expected #<Post id: 1> to not be equal to #<Post id: 1>.

1 runs, 3 assertions, 1 failures, 0 errors, 0 skips

Expected behavior

This should fail spectacularly:

Post.includes(:comments).references(:literally_anything).where("foo_comments.content = ?", 'bar').first

Actual behavior

It magically generates valid SQL and works fine.

SQL (0.1ms)  SELECT "posts"."id" AS t0_r0, "foo_comments"."id" AS t1_r0, "foo_comments"."post_id" AS t1_r1, "foo_comments"."content" AS t1_r2 FROM "posts" LEFT OUTER JOIN "foo_comments" ON "foo_comments"."post_id" = "posts"."id" WHERE (foo_comments.content = 'bar') AND "posts"."id" = 1 ORDER BY "posts"."id" ASC

System configuration

Rails version: 5.0.0 / 5.0.0.1

Ruby version: 2.3.1

I'm really scratching my head on this one. I verified the result on two machines...

@prakashmurthy
Copy link
Contributor

Confirming the behavior on Rails 4/5.

My guess is that the post.comments << Comment.create!(content: 'bar') line caches the values for the relationship, and that makes the correct reference table name available to the later query even though an incorrect table name is specified.

@matthewd
Copy link
Member

# My personal opinion is this *should* work, but the docs say references takes table_name

.. and that's pretty much why references does what it does.

Namely: while it's supposed to be a specific list of things that are referenced, so we can intelligently pick over includes and determine which ones need to be joined... it's actually treated as a boolean flag.

I would hope to make references Actually Intelligent (and thus start emitting deprecations and eventually errors for incorrect parameters) at the same time we get association names working in where (see #13555). Until then, it doesn't seem worth the inconvenience of making everyone revisit their queries; if you specifically want to join some but not others, you can split them between preload and eager_load yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants