Reputation: 5084
My code is rather similar in concept to the railstutorial by Michael Hartl - the following users part, however it is different enough to ask this question.
The problem before all the details:
When I remove the remote: true
from _like, everything works smoothly,
When _like.html.erb has remote: true
I'm getting:
No route matches {:action=>"destroy", :controller=>"likes", :artwork_id=>1} missing required keys: [:id]
And I don't understand why.
The code snippets:
views/artworks
show.html.erb:
<div id="like_link">
<% if @artwork.liked_users.include?(current_user) then %>
<%= render 'unlike' %>
<% else %>
<%= render 'like' %>
<% end%>
</div>
_unlike.html.erb:
<%= link_to 'UNLike', like_path(artwork_id: @artwork.id), method: :delete, remote: true %>
_like.html.erb:
<%= link_to 'Like', likes_path(artwork_id: @artwork.id), method: :post, remote: true %>
views/likes
create.js.erb:
$("#like_link").html("<%= escape_javascript(render("artworks/unlike")) %>")
$("#likes").html('<%= @artwork.likes_count %>')
destroy.js.erb:
$("#like_link").html("<%= escape_javascript(render("artworks/like")) %>")
$("#likes").html('<%= @artwork.likes_count %>')
and the likes controller - controllers/likes_controller.rb
class LikesController < ApplicationController
respond_to :html, :js
def create
@artwork = Artwork.find(params[:artwork_id])
current_user.like!(@artwork)
respond_with @artwork
end
def destroy
@artwork = Artwork.find(params[:artwork_id])
current_user.unlike!(@artwork)
respond_with @artwork
end
end
routes.rb:
resources :artworks
resources :likes, only: [:create, :destroy]
Upvotes: 1
Views: 189
Reputation: 911
here you create routes of
resources :likes, only: [:create, :destroy]
According RAILS convention it create routes for likes controller there it use :id
such as "likes/:id"
not likes/artwork_id
so please create likes routes manually or follow convention.
Upvotes: 1
Reputation: 3083
you do not have o pass artwork id
<%= link_to 'Like', likes_path(@artwork), method: :post, remote: true %>
<%= link_to 'UNLike', like_path(@artwork), method: :delete, remote: true %>
and now you can access this in controller by
params[:id]
Upvotes: 0
Reputation: 38645
Here is the problematic line:
# _like.html.erb
<%= link_to 'Like', likes_path(artwork_id: @artwork.id), method: :post, remote: true %>
The problem here is likes_path(artwork_id: @artwork.id), method: :post
. If you check the output of rake routes
you should see the following two lines for your likes
resources:
likes POST /likes(.:format) likes#create
like DELETE /likes/:id(.:format) likes#destroy
As you can see the likes_path
does not take in a parameter except the format, so your likes_path(artwork_id: @artwork.id)
cannot be mapped to any path.
You should update your route definition with the following:
# app/config/routes.rb
resources :artworks do
resources :likes, only: [:create, :destroy]
end
With this route definition, your link_to
calls will be:
# _like.html.erb
<%= link_to 'Like', artwork_likes_path(artwork_id: @artwork.id), method: :post, remote: true %>
# _unlike.html.erb
# Replace this_like_id with like_id attribute for this like being destroyed.
<%= link_to 'UNLike', artwork_likes_path(artwork_id: @artwork.id, id: this_like_id), method: :delete, remote: true %>
Upvotes: 0