incorrect table aliasing with polymorphic join #273

Closed
the8472 opened this Issue Oct 9, 2013 · 10 comments

2 participants

@the8472

using rails 3.2.14, squeel 1.1.1

class A
  belongs_to :poly, :polymorphic => true
end

class B
  belongs_to :c
end

class C
  has_many :d, :as => :poly
  has_many :xxx, :class_name => "D", :as => :poly, :conditions => {:cond => "foo"}
end

class D
  belongs_to :poly, :polymorphic => true
end

class E
end


A.joins{[poly(B).c.xxx, poly(E).outer]}.where{poly(B).c.xxx.column.in(["value1","value2"])}

resulting query:

SELECT "a".* FROM "a" INNER JOIN "b" ON "b"."id" = "a"."poly_id" AND "a"."poly_type" = 'B' INNER JOIN "c" ON "c"."id" = "b"."c_id" INNER JOIN "d" ON "d"."poly_id" = "c"."id" AND "d"."cond" = 'foo' AND "d"."poly_type" = 'C'  LEFT OUTER JOIN "e" ON "e"."id" = "a"."poly_id" AND "a"."poly_type" = 'E' WHERE "xxx"."column" IN ("value1", "value2")

xxx obviously is not aliased correctly.

I suspect it can't fails to bind the keypath in the where correctly.

@ernie
ActiveRecord Hackery member

@the8472 any chance you can repro a minimal case? Even better if it's in the spec suite. At first glance I'm guessing it's something with the class_name option but I could be wrong.

@ernie
ActiveRecord Hackery member

@the8472 and that's minimal? As in, it's broken only if you use class_name and conditions options on the has_many?

@the8472

Stripped it down some further.

@ernie
ActiveRecord Hackery member

Thanks. Much appreciated. I'll have a look.

@ernie
ActiveRecord Hackery member

Further minimized (it's not dependent on 3.2, but broken in 4.0 as well, and doesn't need a class_name option to illustrate the issue):

#!/usr/bin/env ruby

gem 'activerecord'
gem 'squeel', "~> 1.1"
gem 'sqlite3'

require "active_record"
require "squeel"

ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"

class A < ActiveRecord::Base
  belongs_to :poly, :polymorphic => true
end

class B < ActiveRecord::Base
  has_many :c, :as => :poly
  has_many :xxx, :class_name => "C", :as => :poly
end

class C < ActiveRecord::Base
  belongs_to :poly, :polymorphic => true
end

class E < ActiveRecord::Base
end

puts A.joins{poly(B).c}.where{poly(B).c.column.in(["value1","value2"])}.debug_sql
@the8472

Oh yeah, with the default pluralized table name "cs" for the class C it's visible. I was using singular table names locally and hence it usually showed up on aliased associations and not on the associations that had the same name as the class/table.

@ernie
ActiveRecord Hackery member

Here's the failing spec I'm working from:

          it 'maps conditions onto their proper table with a polymorphic belongs_to join followed by a polymorphic has_many join' do
            relation = Note.joins{notable(Article).notes}.
              where{notable(Article).notes.note.eq('zomg')}
            relation.to_sql.should match /"notes_articles"\."note" = 'zomg'/
          end
@ernie ernie added a commit that closed this issue Oct 9, 2013
@ernie ernie Detect join nodes properly in AR Contexts.
Fixes #273
b14aaa3
@ernie ernie closed this in b14aaa3 Oct 9, 2013
@ernie
ActiveRecord Hackery member

@the8472 This does the trick for my spec. Let me know if it doesn't work for you.

@the8472

Queries look good now. And again, amazing response times from you 👍

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