Reputation: 59232
I've the below in index.html.erb
(Just the important part ad post
is declared)
<%=link_to yay_post_path(post), :remote=>true, class:'btn-default btn' do %>
<span class="glyphicon glyphicon-chevron-up"></span>
<% end %>
<%=link_to nah_post_path(post), :remote=>true, class:'btn btn-default' do %>
<span class="glyphicon glyphicon-chevron-down"></span>
<%end %>
And this in route.rb
resources :posts do
member do
put 'yay', to: 'posts#yay'
put 'nah', to: 'posts#nah'
end
end
And this in PostsController
def yay
@post = Post.find(params[:id])
@post.liked_by current_user
@redirect_to @post
end
def nah
@post = Post.find(params[:id])
@post.downvote_from current_user
@redirect_to @post
end
Note that the above methods don't have their own views. They are just custom methods.
When I click on the link, I get 404 Error saying
cannot find /post/1/yay
What is the fix for this?
Upvotes: 0
Views: 159
Reputation: 50057
You declare the path in the router with html method put
, so you have to adjust your link accordingly. A normal link is always http GET
, but rails will help you when you write:
<%=link_to yay_post_path(post), remote: true, method: :put, class:'btn-default btn' do %>
<span class="glyphicon glyphicon-chevron-up"></span>
<% end %>
so you have to explicitly add the http-method if it differs from the default.
[EDIT: handling js in controller] To handle the js in the controller there are two options:
def yay
respond_to do |format|
format.js do
@post = Post.find(params[:id])
@post.liked_by current_user
head :ok
end
end
end
Note: this will return http status 406 for html calls, which is what I would want :)
A more standard approach would be to
def yay
@post = Post.find(params[:id])
@post.liked_by current_user
respond_to do |format|
format.html { @redirect_to @post }
format.js { head :ok }
end
end
But that depends on what you want to support (e.g. allow to fallback to standard html or not).
If you want to update the view, which I would want (otherwise they could go on yay-ing and nay-ing, unless you handle that browser-side), you could do something like:
def yay
respond_to do |format|
format.js do
@post = Post.find(params[:id])
@post.liked_by current_user
end
end
end
and add a view called yay.js.erb
containing
$('#yays_and_nays').hide()
or e.g. update a part of the view
$(#yays_and_nays').replaceWith('<% escape_javascript(render 'yay_or_nayed_status') %>');
Upvotes: 1