Combining Arel and polymorphic associations

I have the following:

class BaseReseller < ActiveRecord::Base

  set_table_name "resellers"

  acts_as_nested_set

  has_many :merchants, :as => :merchant_owner, :dependent => :destroy
end

class IPSP < BaseReseller
end    

class Agent < BaseReseller
end

class Reseller < BaseReseller
end

class Merchant < ActiveRecord::Base
  belongs_to :merchant_owner, :polymorphic => true
end

class MerchantsController < ApplicationController
  ... 
  def index
    ...
    @merchants = Merchant.joins(:merchant_owner) # breaks!
  end
end

      

Note how I am trying to join a Merchant with a polymorphic merchant and get this: ActiveRecord :: EagerLoadPolymorphicError: Can't eagerly load polymorphic association: merchant_owner .

@merchants = Merchant.includes (: merchant_owner) works natively, but when I start iterating over the @merchants array in the views it breaks with the same error - it seems because we are working with lazy loaded relationships and only when the non-Arel method is called , it actually goes to the DB.

Any ideas? Does Arel support polymorphic association? Any workarounds? I can go down to pure SQL, but this is piggy.

thank

+3


source to share


2 answers


The problem was a missing column in one of the tables. Rails supports polymorphic associations between STI hierarchies very well, but be careful about the correct columns for polymorphism, STI, etc.



0


source


It might be too much to ask Arel, I'm not sure about a great solution. In your case, it looks like all seller-owners are using the same reseller table, so it makes sense to want to join a polymorphic association, but in general polymorphic associations can refer to different models (for different tables) across your entire data model This is going to be pretty ugly in SQL and probably pretty slow in general, so I expect the EagerLoadPolymorphicError to exist. For your situation, it would make sense to work with something like:

Merchant.joins("INNER JOIN resellers on merchant_owner_id = resellers.id")

      

of course it would be cleanest for this join to be a region on your model so you can just do Merchant.joined_with_owners and the SQL assigned to the model layer. This, however, will not work if other non-reseller models have many sellers.



I'm a little surprised that you see the same error with Merchant.includes (: merchant_owner), I don't see it with similar data even when I access different attributes, but it might be due to different differences.

Are you trying to load the load for performance reasons or because you have additional Arel where clauses that depend on the reseller attributes? If it's for performance, you might be better off falling back on SQL ...

0


source







All Articles