how to fix “No route matches [PATCH]”

2019-06-05 02:54发布

问题:

I am a newbie to ruby on rails. I was working on a project and run into an issue with a form. I am using devise for authentication. I have a user class which has admin and user roles. The devise generated add/ update methods for user is working properly. I am running into a 'No route matches [PATCH]' error when I am trying to create an edit page for the admins. here is the form I am using

<h4>Update Profile</h4>
 <%= form_for @user, :url => {:controller => "admin", :action => "update" }  do |f|  %>

<%= hidden_field_tag(:id, @user.id) %>
<table>
  <tr>
    <td>First Name</td>
    <td><%= f.text_field  :first_name , :class => "form-control"%></td>
  </tr>
  <tr>
    <td>Last Name</td>
    <td><%= f.text_field  :last_name , :class => "form-control"%></td>
  </tr>
  <tr>
    <td>Email</td>
    <td><%= f.text_field  :email , :class => "form-control"%></td>
  </tr>
  <tr>
    <td></td>
    <td><%= f.submit "Update", :class => "btn btn-md btn-success pull-right" %></td>
  </tr>
</table>

<%end%>

This is my controller method

def edit
end

def update
  @user = User.find(params[:id])
  if request.post?
     if(@user.update_attributes(params[:first_name, :last_name, :email] ))
      redirect_to :action =>  "admin_portal"
  else
    render :action => "edit"
  end
end

end

I also have the route

get 'admin/update'
 get 'admin/edit'

Can anyone suggest how I can fix this issue.

回答1:

The point is: you are setting only GET from HTTP's methods, and for updates, you need a PUT or a PATCH method. There are some conventions when to use PUT or PATCH, but in your case, making a PATCH route would solve your problem as you said

patch 'admin/:1'

But, apparently you are writing yourself a route for every REST method, and Rails has a "helper" structure called resources that create all the REST methods for your. You could create just one entrance on your config/routes.rb like:

resources :admins

and it would generate every route intended for the REST methods pointing for your user_controller and renamed as admin. Putting only that line of code, is be equivalent to write all these commands on your config/routes:

get 'admins', controller: 'admins', action: :index
get 'admin/:id', controller: 'admins', action: :show
get 'admin/new', controller: 'admins', action: :new
get 'admin/:id/edit', controller: 'admins', action: :edit
post 'admin', controller: 'admins', action: :create
patch 'admin/:id', controller: 'admins', action: :update
put 'admin/:id', controller: 'admins', action: :update
delete 'admin/:id', controller: 'admins', action: :delete

You can see more on Rails guides. It has many useful advices on creating routes.



回答2:

It's because you have form_for @user for persisted model it generates patch, and you only have get in routes. Change get to patch. More info http://guides.rubyonrails.org/routing.html