Amit Joki
Amit Joki

Reputation: 59232

link_to is not triggering the action

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

Answers (2)

nathanvda
nathanvda

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:

return nothing

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

Milind
Milind

Reputation: 5112

in your routes...

put 'yay', to: 'posts#yay'

its PUT,So you need to include :method=>"put"in link_to as well..refer this ApiDock

Upvotes: 0

Related Questions