0

Given assessments and messages sent by a member, I'd like to find all the logs associated to a member with a specific email. I am running into issues joining polymorphic associations EagerLoadPolymorphicError Cannot eagerly load the polymorphic association . I assume I should join Log with the consumer association and then add a conditional for the members email.

I am using Rails 6.0.3.7

My models are the following:

class Assessment
    belongs_to :member, foreign_key: 'sender_id'
    has_one :log, as: :consumer
end

class Message
    belongs_to :member, foreign_key: 'sender_id'
    has_one :log, as: :consumer
end

class Log

   belongs_to :consumer, polymorphic: true
end

class Member
   has_many :assessments
   has_many :messages
end  

I have tried various forms of the following:

Log.joins(consumer: :member).where(members: {email: 'john@cheese.com'})
#ActiveRecord::EagerLoadPolymorphicError (Cannot eagerly load the polymorphic association :consumer)

I then thought perhaps I could do a belongs_to :through but apparently that's no good either belongs_to through associations. Is what I am trying to do even possible?

pigusan
  • 109
  • 9

2 Answers2

1

Since there is no table called consumer, joins will fail on this. To solve this problem you can write a custom join.

Try this:

member = Member.find_by(email: 'test1@gmail.com')
Log.joins("LEFT JOIN messages ON (messages.id = logs.consumer_id AND consumer_type='Message')")
   .joins("LEFT JOIN assessments ON (assessments.id = logs.consumer_id AND consumer_type='Assessment')")
   .where('messages.member_id = ? or assessments.member_id = ?', member.id, member.id)

You can nested joins as well to join with members table, notice the AS in the second nested join:

Log.joins("LEFT JOIN messages ON (messages.id = logs.consumer_id AND consumer_type='Message')")
   .joins("LEFT JOIN assessments ON (assessments.id = logs.consumer_id AND consumer_type='Assessment')")
   .joins('LEFT JOIN members ON members.id = messages.member_id')
   .joins('LEFT JOIN members AS mmbrs ON mmbrs.id = assessments.member_id')
   .where('members.email = ? OR mmbrs.email = ?', 
          'john@cheese.com', 'john@cheese.com')

Mosaaleb
  • 1,028
  • 1
  • 9
  • 23
  • This requires me to find the member first, is there a way to joins the members table so I can simply pass in the email? – pigusan Aug 09 '21 at 13:34
0

You can try using includes which perhaps can deal with polymorphic associations. Joins actually looks for a consumers table which doesn't exist.

Log.includes(consumer: :member).where(members: {email: 'john@cheese.com'})
Joel Blum
  • 7,750
  • 10
  • 41
  • 60
  • I get ActiveRecord::ConfigurationError (Can't join 'Log' to association named 'consumer'; perhaps you misspelled it?) – pigusan Aug 09 '21 at 13:33