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.

has_one :through using belongs_to produces incorrect SQL

#1167

Using the following model classes:

class Foo < ActiveRecord::Base
end

class Bar < ActiveRecord::Base
  belongs_to :foo
end

class Baz < ActiveRecord::Base
  belongs_to :bar
  has_one :foo, :through => :bar
end

The following code:

Baz.create.foo

will result in a SQL query with an incorrect WHERE clause and an exception similar to the following:

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such
column: bars.bar_id: SELECT "foos".* FROM "foos"
INNER JOIN bars ON foos.id = bars.foo_id
WHERE (("bars".bar_id = 1))

I'v attached a test case which proves the bug.

Reported by John Wilger · October 4th, 2008 @ 01:54 AM

State: resolved
Milestone: 2.x
Assigned to: Frederick Cheung Frederick Cheung
Importance: none

Activity

  1. Dan Pickett
    Dan Pickett

    I've experienced the same issue - I will try to work on a patch this week

    November 2nd, 2008 @ 02:44 PM

  2. Frederick Cheung
    Frederick Cheung

    The root cause was that has_one through is a special case of has_many through and has many through didn't allow the through reflection to be a belongs_to.

    This was fixed for 2.2 in this commit which resolves the has one through issue too.

    December 20th, 2008 @ 01:53 PM

  3. Frederick Cheung
    Frederick Cheung
    • State changed from new to resolved

    December 20th, 2008 @ 02:00 PM

  4. Glenn Powell
    Glenn Powell

    I'm actually still seeing something which I believe is a result of this problem. I have the same relationship as above:

    class Foo < ActiveRecord::Base end

    class Bar < ActiveRecord::Base belongs_to :foo end

    class Bat < ActiveRecord::Base belongs_to :bar has_one :foo, :through => :bar end

    (I use Bat because it's easier to pluralize than Baz) If I call the through attribute directly, then it works:

    Bat.first.foo => #

    But if I try to include the :foo association in any find conditions, then I get a similar error to the one above.

    Bat.all(:include => :foo, :conditions => { 'foos.id' => 1 }) ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'bars.bar_id' in 'on clause': SELECT bats.id AS t0_r0, bat.bar_id AS t0_r1, foos.id AS t1_r0 FROM bats LEFT OUTER JOIN bars ON (bats.id = bars.bar_id) LEFT OUTER JOIN foos ON (foos.id = bats.foo_id) WHERE (foos.id = 1)

    It seems as though the join on condition (bats.id = bars.bar_id) has simply reversed the foreign/primary keys here. So it should be: bats.bar_id = bars.id Correct?

    February 2nd, 2009 @ 04:01 PM

  5. Glenn Powell
    Glenn Powell

    My post got chewed up, but I think you can see the gist of it

    February 2nd, 2009 @ 04:02 PM

  6. Brian Landau
    Brian Landau

    I can confirm that I'm experiencing the same issues as Glenn is. Where the foreign/primary keys seem reversed (or something along those lines).

    Can we see this no longer marked as "resolved"?

    February 12th, 2009 @ 09:20 PM

  7. ronin-38963 (at lighthouseapp)
    ronin-38963 (at lighthouseapp)

    I'm having the same problem when I search Baz for Foos with a certain attr using a named scope defined in Baz in ActiveRecord 2.3.

    Baz.with_Foo_attr(attr) yields: ActiveRecord::StatementInvalid: PGError: ERROR: column bars.bar_id does not exist

    Baz.first.Foo works.

    April 24th, 2009 @ 09:24 PM

  8. ronin-38963 (at lighthouseapp)
    ronin-38963 (at lighthouseapp)

    Turns out I had my :joins statement wrong--sorry.

    April 24th, 2009 @ 09:35 PM

  9. Emrys Ingersoll
    Emrys Ingersoll

    I can also confirm this is still an issue.

    September 23rd, 2009 @ 04:02 PM

  10. Dan Pickett
    Dan Pickett

    I've attached a patch that verifies this is fixed in 2-3-stable with a concrete test case. Please review and advise

    October 28th, 2009 @ 10:08 PM

  11. Dan Pickett
    Dan Pickett
    • Assigned user set to Frederick Cheung

    October 28th, 2009 @ 10:08 PM

  12. Matthew Vincent
    Matthew Vincent

    I am having this issue with 2.3.4, the issue isn't so much in the has_one :through a belongs_to relationship. Using Dan's patch example, there is no issue doing membership.member_type. However, it breaks once you do something more complex such as:

    Membership.find :first, :include=>:member_type, :conditions=>['member_types.type = ?','VIP']
    

    Would produce an error

    ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'members.member_id'

    My specific example is as follows, and maybe I just have something incorrectly setup:

    class Locus < ActiveRecord::Base
      belongs_to :square
      has_many :artifacts
    end
    
    class Artifact 
      belongs_to :locus
      has_one :square, :through=>:locus
    end
    

    So now if I want to find all the objects found in one excavation square, I would do the following:

    Artifact.find :all, :include=>:square, :conditions=>['squares.code = ?','8K11']
    

    Which instead produces the error:

    ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'loci.locus_id'

    Any thoughts?

    November 13th, 2009 @ 05:23 PM