27

I'm pretty new to Rails, and i'm trying to do a polymorphic HABTM relationship. The problem is that I have three models that I want to relate.

The first one is the Event model and then are two kind of attendees: Users and Contacts.

What I want to do is to be able to relate as an attendee both users and contacts. So, what i have right now in my code is:

Event Model

has_and_belongs_to_many :attendees, :polymorphic => true

User Model

has_and_belongs_to_many :events, :as => :attendees

Contact Model

has_and_belongs_to_may :events, :as => :attendees
  1. How the HABTM table migration needs to be? I'm a little confused and i have found no help on that.
  2. Is it going to work?
Makoto
  • 104,088
  • 27
  • 192
  • 230
Mateus Pinheiro
  • 870
  • 2
  • 12
  • 20

2 Answers2

65

No, you can't do that, there's no such thing as a polymorphic has_and_belongs_to_many association.

What you can do is create a middle model. It would probably be something like this:

class Subscription < ActiveRecord::Base
  belongs_to :attendee, :polymorphic => true
  belongs_to :event
end

class Event < ActiveRecord::Base
  has_many :subscriptions
end

class User < ActiveRecord::Base
  has_many :subscriptions, :as => :attendee
  has_many :events, :through => :subscriptions
end

class Contact < ActiveRecord::Base
  has_many :subscriptions, :as => :attendee
  has_many :events, :through => :subscriptions
end

This way the Subscription model behaves like the link table in a N:N relationship but allows you to have the polymorphic behavior to the Event.

Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158
  • 1
    Could anyone expand upon this? How to set up the migrations? How to create a relationship? – Erick Maynard Jun 11 '18 at 09:22
  • The migration would just need to address the belongs_to relationships for polymorphism. The rails docs cover this, glad to help if you need it. The relationships are there - not sure what you are asking. The has many through connects the objects in the habtm relationship. – Joe Jul 13 '18 at 16:43
  • this may have changed in the meantime? looks like Rails now supports `has_and_belongs_to_many` without a middle table: https://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association – JohnRDOrazio Jul 14 '21 at 07:13
0

Resolveu parcialmente.

It does solve the problem given the framework that we have at our disposal, but it adds "unnecessary" complexity and code. By creating an intermediary model (which I will call B), and given A -> B -> C being "A has_many B's which has_many C's", we have another AR Model which will load one more AR class implementation into memory once it is loaded, and will instantiate for the sole purpose of reaching C instances. You can always say, if you use the :through association, you don't load the B association, but then you'll be left with an even more obsolete model, which will only be there to see the caravan pass by.

In fact, this might be a feature that is missing from Active Record. I would propose it as a feature to add, since it has been cause of concern for myself (that's how I landed in this post hoping to find a solution :) ).

Cumprimentos

ChuckE
  • 5,610
  • 4
  • 31
  • 59