简体   繁体   中英

Rails 'update' action not found

I have the following UsersController, and when I am on the "edit" action, I can edit my data and click the "submit" button. Upon clicking the submit button I get the folowing error.
The action 'update' could not be found for UsersController I don't understand why it is even trying to go the 'update' action in the first place. Can someone point me in the right direction?

UsersController

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.create!(user_params)
    redirect_to users_path, notice: "Successfully created #{@user.name}"
  end

  def index
    @user = User.find(session[:user_id])
    if @user == current_user
      render :index
    else
      redirect_to new_session_path, notice: "You need to login first to view schedules."
    end
  end

  def edit
    @user = User.find(params[:id])
    if @user == current_user
      render :edit
    else
      redirect_to users_path, notice: "You do not have permission to edit #{@user.name}'s profile."
    end
  end

  private

  def user_params
    params.require(:user).permit!
  end
end

Here is my edit view, and my form - helper view. edit:

<div class="page-header">
  <div class="row">
    <h1 class="col-sm-8" style="margin-left: 10px"><%= link_to @user.name, edit_user_path(@user) %></h1>
    <div class="col-sm-3">
      <span style="margin-right: 20px"><%= link_to 'Logout', 'logout', class: 'btn btn-default pull-right' %></span>
      <span style="margin-right: 20px"><%= link_to 'Home', users_path, class: 'btn btn-default pull-right' %></span>
      <span style="margin-right: 20px"><%= link_to 'My Studio', studios_path, class: 'btn btn-default pull-right' %></span>
    </div>
  </div>
</div>

<%= render partial: 'form', locals: {submit_copy: 'Edit this user'} %>

_form:

<div class="row col-sm-6" style="margin-left: 30px;">
  <%= form_for @user do |f| %>
    <div class="form-group">
      <%= f.label :email %>
      <%= f.text_field :email, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.label :password_confirmation %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.label 'Select Your Studio' %> &nbsp;or <%= link_to 'Add Your Studio', new_studio_path %>
      <%= f.collection_select :studio_id, Studio.all, :id, :name, {}, {class: 'form-control'} %>
    </div>

    <div class="form-group">
      <%= f.label :role, 'Role' %>
      <%= f.text_field :role, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.label :image_url, 'Image URL' %>
      <%= f.text_field :image_url, class: 'form-control' %>
    </div>

    <%= f.submit submit_copy, class: 'btn btn-primary' %>
    &nbsp;or
    <%= link_to 'Cancel', new_session_path %>
  <% end %>
</div>

You should read some of rails basic documentation, in particular the REST explanation of rails.

by convention

  • edit is the action that renders the edit form (accessed by GET )
  • update is the action that actually updates the record (accessed by PUT )

So in your case the form is rendered by the edit method and then the submit sends you to the update action.

Which means that you have to implement it as well.

Since you're passing @user as an argument of form_for , Rails will call #persisted? on @user , with two possible outcomes:

  • If the return is true that means it's an existing object that is being updated, and the form will be submitted to the #update action.
  • If the return is false that means it's a new object, and the form will be submitted to the #create action.

If you're curious as to how Rails performs those checks, you can take a look at the ActionView module in the source code:

https://github.com/rails/rails/blob/4-1-stable/actionview/lib/action_view/helpers/form_helper.rb#L1808-L1824

More specifically, at line number 1810:

key    = object ? (object.persisted? ? :update : :create) : :submit

When the object you are passing to the form_for helper is already persisted, it will create a form for updating the object, with the following attributes.

<form action="/users/:id" method="post"> 

Assuming you have default routing in your routes.rb file

resources :users

This will generate several restful routes, one of which is a route for updating a resource.

PATCH/PUT  /users/:id  users#update

Then you submit the form a post request will be made to /users/:id with form data and the request will be routed to update action of UsersController.

You should add the update method to the controller and save the edited object there.

You can learn more about Rails routing here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM