ActiveRecord::EagerLoadPolymorphicError: Can not eagerly load the polymorphic association
Asked Answered
A

3

11
class Transaction < ActiveRecord::Base
  belongs_to :account, :polymorphic => true
end

class Bankaccount < ActiveRecord::Base
  has_many :transactions, :as => :account
end

class Creditcard < ActiveRecord::Base
  has_many :transactions, :as => :account
end

Trying to do a summation of transactions where the account is active.

Transaction.sum(:all, :conditions => "account.status = 'active'", :include => :account)

So after some reading I came across this: The reason is that the parent model‘s type is a column value so its corresponding table name cannot be put in the FROM/JOIN clauses of that query. The table name is bankaccounts and creditcards so does that mean they should be singular? Also the account_type is a string either Bankaccount or Creditcard to reflect the model but should it be the tablename instead?

Anthelion answered 17/1, 2010 at 3:32 Comment(0)
M
19

There are two issues here:

  1. Summing over a polymorphic association.
  2. Condition over a polymorphic association.

You can't actually do either of these things. So you should get the same error by performing these two queries:

  1. Transactions.count(:all, :joins => :account)
  2. Transactions.find(:all, :conditions => "accounts.status = 'active'", :joins => :account)

To actually get the information you need you must explicitly list out the possible parent polymorphic associations. One way to do this is to simply use SQL and LEFT JOINS, so that you can use a single query. Using Rails this can be performed with two queries:

Creditcard.sum(
  :all, 
  :select => "transactions.amount", 
  :conditions => "creditcards.status = 'active'", 
  :joins => :transaction
) + Bankaccount.sum(
  :all, 
  :select => "transactions.amount", 
  :conditions => "bankaccounts.status = 'active'", 
  :joins => :transaction
)

P.S: It's best to use :join instead of :include if you don't plan on accessing the joined objects after the query.

Maryannmaryanna answered 22/8, 2010 at 20:18 Comment(2)
Thanks for answering my question and yeah eventually went that same route. Thanks again Pan :DAnthelion
Spot on. Also look at this answer for joining polymorphic models: https://mcmap.net/q/344651/-activerecord-querying-polymorphic-associationsIrrecoverable
P
2

For those that got this error even when they aren't trying to query conditions on the polymorphic association, it's because includes decided to call eager_load when polymorphic associations are only supported by preload. It's in the documentation here: http://api.rubyonrails.org/v5.1/classes/ActiveRecord/EagerLoadPolymorphicError.html

So you should always use preload for polymorphic associations.

Percy answered 19/10, 2017 at 20:49 Comment(0)
J
0

Additional to pan's answer, you could even do a union instead of adding them. which executes only one query

Judicator answered 17/12, 2014 at 13:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.