Rapture
Rapture

Reputation: 1896

Routing Error - No route matches [PATCH] but resource defined

I'm getting an error in my rails app when trying to set up an edit form:

ActionController::RoutingError (No route matches [PATCH] "/contact.5")

When I inspect my form in the edit view I see the action is incorrect as well

<form class="edit_contact" id="edit_contact_5" action="/contact.5" ...

I have created a complete resource in my routes file for my contact controller:

resources :contacts

When I rake routes I get the following for contacts:

contact  GET    /contact(.:format)           static_pages#contact
contacts GET    /contacts(.:format)          contacts#index
         POST   /contacts(.:format)          contacts#create
new_contact GET    /contacts/new(.:format)      contacts#new
edit_contact GET    /contacts/:id/edit(.:format) contacts#edit
         GET    /contacts/:id(.:format)      contacts#show
         PATCH  /contacts/:id(.:format)      contacts#update
         PUT    /contacts/:id(.:format)      contacts#update
         DELETE /contacts/:id(.:format)      contacts#destroy

I have a shared form for creating and editing a contact in app/views/shared/_contact_form.html.erb. This form is properly displaying the new and edit actions. This form is saving new contacts properly, but throws the error above when attempting to update a contact.

<%= form_for(@contact) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>
  ...
  <%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>

My edit view calls the partial like this:

<% provide(:title, 'Edit Contact') %>
<% provide(:button_text, 'Update Contact') %>

<h1>Update <%= @contact.name =%></h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'shared/contact_form' %>
  </div>
</div>

Here are the edit and update actions in the controller:

def edit
  @contact = Contact.find(params[:id])
end

def update
  @contact = Contact.find(params[:id])
  if @contact.update_attributes(contact_params)
    flash[:success] = "Contact Updated"
    redirect_to current_user
  else
    render 'edit'
  end
end

I'm using this same pattern for creating and updating my users and it seems to work just fine. This seems like it should be quite straight forward. Can anyone help me spot my error?

Upvotes: 1

Views: 1076

Answers (1)

Thong Kuah
Thong Kuah

Reputation: 3283

Ah yes, there is a conflict in the routes.rb.

what form_for(@contact) does is equivalent to :

form_for @contact, as: :contact, url: contact_path(@contact), method: :patch, html: { class: "edit_contact", id: "edit_contact_45" }

[1] http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for

Based on the screenshot, you have the singular contact => static_pages#contact route listed, which looks like it has precedence over the contacts resource paths, specifically the path generated for the update action.

If you remove or modify the static_pages#contact route to not conflict with the resources contacts route, then your edit/update form should then work.

Upvotes: 2

Related Questions