A user has many playlists through the owner_id foreign key, but they also make many contributions to playlists through the playlist_user join table. Vice versa, a playlist has an owner through their owner_id foreign key, but they also have many contributors through the playlist_user join table.
There’s actually two steps in implementing the relationship I previously described. The first is to create a direct relationship between the users and playlists through the owner_id foreign key. This can be done by setting up has_many and belongs_to relation:
class Playlist < ActiveRecord::Base
belongs_to :owner, class_name: "User"
end
class User < ActiveRecord::Base
has_many :playlists, :foreign_key => 'owner_id'
end
Now we can call something like:
playlist.owner #=> returns the current playlist's owner
user.playlists #=> returns the user's playlists that they own/created
The next step is to alias the has_many through relation with the join table. It turns out it’s pretty straight forward. You just have to declare the has_many with whatever alias you want to give the association, through the join table, and then specify the source, which is the table you want to join to. In this specific case, our code will look as follows:
class Playlist < ActiveRecord::Base
has_many :playlist_users
has_many :contributors, through: :playlist_users, source: :user
end
class User < ActiveRecord::Base
has_many :playlist_users
has_many :contributions, through: :playlist_users, source: :playlist
end
This association will now allow us to call things like:
playlist.contributors #=> returns the list of users that are allowed to contribute to the playlist
user.contributions #=> returns the list of playlists the the user does not own, but can contribute to
Cool! Now our code is a little bit more legible thanks to a few extra configurations. Until next time, happy coding!