Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

JoinAssociation#aliased_table_name_for bug affecting AR find_with_associations?

#4463

While working on a gem, I was making use of the JoinDependency feature where you can supply some existing SQL on initialization to keep aliased_table_name_for from reusing table names in those joins. I encountered a problem in the interaction between aliased_table_name_for, find_with_associations (finder_methods.rb), and build_arel (query_methods.rb)

First: aliased_table_name_for looks at parent#table_joins for this SQL, but therefore only correctly detects table names used outside of the JoinDependency for a top-level join, since this join_sql is not passed down through associations when calling "super(reflection.klass)" in JoinAssociation#initialize.

Second: the order in which build_arel (query_methods.rb) builds a query reverses the "simulated" JoinDependency used to create the outer joins added by find_with_associations, and so ends up reusing column names anyway, regardless of that fact.

This leads to (where Article has_many :comments, has_many :moderations, :through => :comments):

Article.joins(:comments).eager_load(:moderations) ActiveRecord::StatementInvalid: SQLite3::SQLException: ambiguous column name: comments.article_id ...

The fix as I see it involves determining the user-supplied joins in advance of any association joins and supplying that SQL to JoinDependency.new in build_arel to prevent table name collisions.

I have this fixed in my gem at http://github.com/ernie/meta_where/tree/autojoin and would be happy to port the fix to a patch with tests if this is confirmed as a bug.

Reported by Ernie Miller · April 23rd, 2010 @ 04:11 PM

State: committed
Milestone: 3.0.2
Assigned to: Pratik Pratik
Importance: Low

Activity

  1. Jeremy Kemper
    Jeremy Kemper
    • Milestone cleared.
    • State changed from new to open
    • Assigned user set to Pratik

    Indeed! Tricky one; good diagnosis.

    April 23rd, 2010 @ 05:37 PM

  2. Pratik
    Pratik

    @Ernie : Patch w/ tests please :)

    April 23rd, 2010 @ 05:48 PM

  3. Ernie Miller
  4. Ernie Miller
    Ernie Miller
    • Tag changed from activerecord, eager_loading, find_with_associations to activerecord, eager_loading, find_with_associations, patch, tests

    April 24th, 2010 @ 01:44 AM

  5. Ernie Miller
    Ernie Miller

    One small cleanup to patch and an updated test.

    April 26th, 2010 @ 10:01 PM

  6. Ernie Miller
    Ernie Miller

    Optimized patch and found a bug in association counts with the old version.

    April 29th, 2010 @ 04:20 AM

  7. Ernie Miller
    Ernie Miller
    • Tag changed from activerecord, eager_loading, find_with_associations, patch, tests to activerecord, eager_loading, find_with_associations, patch, tests, updated

    April 29th, 2010 @ 04:21 AM

  8. Repository
  9. Ernie Miller
    Ernie Miller

    Made a silly mistake in the previous patch, checking is_a? instead of class equality. Since JoinAssociation inherits from JoinBase, this can cause a stashed association join to be grafted onto the JoinBase instead of a JoinAssociation in the edge case of multiple-self-joining eager loads. Patch with test included. Sorry about that!

    May 22nd, 2010 @ 08:32 PM

  10. Ernie Miller
    Ernie Miller
    • Tag changed from activerecord, eager_loading, find_with_associations, patch, tests, updated to activerecord, eager_loading, find_with_associations, fixed, patch, tests, updated, updated_again

    May 23rd, 2010 @ 02:11 PM

  11. Jeremy Kemper
    Jeremy Kemper
    • Milestone set to 3.0.2
    • Importance changed from to Low

    October 15th, 2010 @ 11:01 PM