Search code examples
ruby-on-railsturbolinks

Getting No route matches [POST] when using turbolinks


I have todo list app. In the application there are multiple places wher you can mark a todo done by clicking in a checkbox.

This is the erb

<% @todos.each do |todo|%>
 <%= form_for todo, remote: true do |f| %>
  <%= f.check_box :completed, :class => "dashboard_done_box", :id => todo.id %>
 <% end %>
<% end %>

and here's the js

$(document).on('click', ".dashboard_done_box", function(){
 $("#edit_todo_" + $(this).attr('id')).submit()
});

The routes.rb has the line

resources :todos

When I refresh the page it works, but when I am navigating to it I get this error.

Started POST "/todos/1" for 127.0.0.1 at 2014-05-07 13:18:45 +0200
ActionController::RoutingError (No route matches [POST] "/todos/1"):

It also works when I disable turbolinks.

This code works on other pages in my application it is just on one page I have this problem.

When it works in makes a PATCH request

Started PATCH "/todos/1" for 127.0.0.1 at 2014-05-07 13:44:08 +0200
Processing by TodosController#update as JS

Why does it do a POST request and how is it connected to turbolinks?

Update

Yosep Kim suggested I should make a post route

routes.rb

post 'todos/:id'  => 'todos#update', :as => :todo_update

The form

<%= form_for @todo, remote: true, url: todo_update_path(@todo), method: :post do |f| %>

Now I get trough to the controller, but only with these parameters

{"controller"=>"todos", "action"=>"update", "id"=>"3"}

Conclusion: The form submission is not getting serialized. Why?


Solution

  • How does the form render?

    Rails uses the PATCH verb to update because in rails applications a update is almost always a partial update. The PUT verb should be used for complete updates ( like when you overwrite a file ) Read more here Riding With Rails

    Rails uses hidden fields to accommodate the html verb.

    Your form should render like this

    <form accept-charset="UTF-8" action="/todos/5" class="edit_todo" data-remote="true" id="roster_edit_done_todo_5" method="post">
      <div style="display:none">
        <input name="utf8" type="hidden" value="✓">
        <input name="_method" type="hidden" value="patch">
      </div>
     <!-- What ever fields you need -->
    </form>
    

    Be aware if you have the form in a table. The table might make the form render strange.