Hello everyone! How would I setup a has_many relation between two STI models?
Say I have:
Asset < ApplicationRecord Song < Asset Collection < ApplicationRecord Playlist < Collection.
How would I let Playlist have many songs? In models without the STI I simply did
has_and_belongs_to but it doesn’t seem to work with the STI in place. I probably need a join table model but I’m confused on how that should look like
I almost got it to work by having a joint model
class AssetsCollection < ApplicationRecord belongs_to :collection, polymorphic: true belongs_to :asset, polymorphic: true end
and then having:
class Playlist < Collection has_many :assets_collections, as: :collection has_many :songs, through: :assets_collections, source: :asset, source_type: "Song" end class Song < Asset has_many :assets_collections, as: :asset has_many :playlists, through: :assets_collections, source: :collection, source_type: "Playlist" end
This is the “expanded” method (I usually did
def patch_playlist @playlist = Playlist.find(params[:id]) song_ids = params[:selected_songs]&.map(&:to_i) ||  songs = Song.where(id: song_ids) if song_ids.blank? @playlist.songs =  else @playlist.songs = songs end if @playlist.save redirect_back_or_to collections_path, notice: "Songs added to playlist.", status: :ok debugger else redirect_back_or_to collections_path, alert: "Songs could not be added to playlist." + @playlist.errors.full_messages, status: :unprocessable_entity end end
When I inspect
@playlist.songs (in the debugger inside the method ) I can see the songs inside just fine, assign them to a variable,
put their attributes etc. In another method that requests the same playlist, and in the general interactive console though,
playlist.songs is always empty. I’m left with some garbage
playlist.assets_collections which just have an id and created_at