I am building a music streaming app and am busy with Likes functionality. The flow is that a user sees a list of tracks and then likes a track. Then, the user navigates to a Likes page where they can see all of the tracks they liked.
When the user clicks the "heart" icon, I am attempting to use simple_form which has two hidden fields. One field is populated with track.id , the other field should take a @likes.id. However, as the user is not supposed to create a "Likes Playlist", I do not have a likes_id available.
As expected, the error that comes up when navigating to likes page is Couldn't find Like without an ID
Question: Can anyone clarify how I might create a likes_id without having to create one in new.html.erb?
Side note: the user can currently create multiple playlist and can add songs to the chosen playlist, I tried following that same logic for Likes so apologies if I am way off.
Here is my routes
resources :likes do
resources :tracks
end
User Model
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :playlists
has_many :tracks
has_many :albums
has_many :likes
has_one_attached :photo
end
Likes model
class Like < ApplicationRecord
has_many :liked_tracks
has_many :tracks, through: :liked_tracks
belongs_to :user
has_one_attached :photo
end
Here is my join table between tracks and likes
class LikedTrack < ApplicationRecord
belongs_to :like
belongs_to :track
end
My tracks Model
class Track < ApplicationRecord
belongs_to :album
belongs_to :user
has_many :playlist_tracks
has_many :playlists, through: :playlist_tracks
has_many :likes, through: :liked_tracks
has_many :tags, through: :tags_tracks
accepts_nested_attributes_for :playlist_tracks, allow_destroy: true
validates :title, presence: true, length: { in: 1..20 }
validates :description, presence: true, length: { in: 10..60 }
has_one_attached :photo
has_one_attached :track
end
Here is my Likes Controller
class LikesController < ApplicationController
def index
@tracks = LikedTrack.all
end
def show
@liked = Like.find(params[:id])
@tracks = @liked.tracks
end
def new
@liked = Like.new
end
def create
@liked = Like.new(track_params)
@liked.user = current_user
if @liked.save!
redirect_to likes_path(@liked)
else
render 'new'
end
end
private
def track_params
params.require(:liked_track).permit(:track_id, :like_id)
end
end
Here is my LikedTracks controller
class LikedTracksController < ApplicationController
def new
@liked = Like.new
end
def create
@liked_track = LikedTrack.new(liked_track_params)
if @liked_track.save!
redirect_to station_index_path
else
render 'new'
end
end
private
def liked_track_params
params.require(:liked_track).permit(:track_id, :like_id)
end
end
This is my navigation to likes page
<div class="flex">
<i class="fas fa-heart"></i>
<%= link_to "Liked", likes_path(current_user), class: "nav-text" %>
</div>
This is the form embedded within each track card
<%= simple_form_for @liked_track, url: liked_tracks_path, method: :post do |f| %>
<%= f.input :like_id, as: :hidden, input_html: { value: DESIRED @likes.id} %>
<%= f.input :track_id, as: :hidden, input_html: { value: track.id } %>
<%= button_tag type: 'submit', class: "like-button", id: "like-button" do %>
<i class="fas fa-heart"></i>
<% end %>
Tracks should render on the index page of Likes (index.html.erb).
Thanks and hope my provided code isn't an overkill. Let me know if you need an update to this post!
Yes, your logic is a bit weird here, you can simplify everything with the following:
Likemodel and database table (not sure why do you want to attach a photo here?)LikedTrackto belong toUserinstead ofLikeLikedTracktoLikeNow you only need to create a new Like record when user clicks the "heart" button, it should take the
track_idanduser_idas arguments behind your form.