We want to use many-to-many relationships to allow our posts to be "liked" by other users. The reason this is a many-to-many relationship is because:
Post
can have many User
s that liked the photoUser
can have many Post
s that they've likedThe end goal of this is that we should be able to ask for:
@photo = ...
@photo.users_liked # => Should return a list of Users who liked this photo!
@user = ...
@user.posts_liked # => Should return a list of Photos this user liked!
Let's begin by running a generator to create our Like
model (this gets run in your terminal):
rails generate model Like user:references post:references
Remember to migrate your database after this runs, to update your table structure with the new Like
model.
Take a look at our Like
model that was generated to see that it is a "junction" or "join" model between Post
and User
(by belonging to both models).
Next, we'll add two has_many
relations to our Post
model:
class Post
has_many :likes
has_many :users_liked, through: :likes, source: :user
end
🧐What's with this source
business?
The reason why this code looks a bit different than the Book
and Author
is because we want to be able access users who liked this post with @post.users_liked
instead of @post.users
(it's more descriptive!).
Rails was able to imply which field we wanted from Authorship
between Book
s and Author
s because we were accessing it as @book.authors
and @author.books
, but if we want to call it something else, we have to be a bit more explicit, as above, with source
.
Next, try adding the reverse has_many
to the User
model. It should look very similar to the has_many
above.