如何在Ruby on Rails中使用同一表单进行创建和编辑

10
我是一名新手,刚开始接触 Ruby。我有一个表单,但需要根据需要执行创建/更新操作。现在的问题是,每当我调用编辑时,不是编辑现有用户的详细信息,而是得到一个具有编辑后详细信息的新用户。简单地说,我认为每当我执行编辑操作时,都会调用创建方法。
因此,是否有办法使用单个表单进行新建和编辑,而不是使用不同的表单。
以下代码用于编辑用户详细信息:
         <%= link_to 'Home', root_path %>
        <h2>Edit user</h2>
        <%= form_for :user, url: user_index_path do |f| %>
          <p>
            <%= f.label :name %><br>
            <%= f.text_field :name %>
          </p>

          <p>
            <%= f.label :address %><br>
            <%= f.text_area :address %>
          </p>
         <p>
            <%= f.label :email %><br>
            <%= f.text_field :email %>
          </p> 
         <p>
            <%= f.label :phone %><br>
            <%= f.text_field :phone %>
          </p>
          <p>
            <%= f.label :state %><br>
            <%= f.text_field :state %>
          </p>
          <p>
            <%= f.label :country %> 
            <%= f.collection_select(:country, Country.all, :name, :name) %>
          </p>
          <p>
            <%= f.submit %>
          </p>
        <% end %>

以下代码是用于创建用户的:

        <%= link_to 'Home', root_path %>
    <h2>Create new user</h2>
    <%= form_for :user, url: user_index_path do |f| %>
      <p>
        <%= f.label :name %><br>
        <%= f.text_field :name %>
      </p>

      <p>
        <%= f.label :address %><br>
        <%= f.text_area :address %>
      </p>
     <p>
        <%= f.label :email %><br>
        <%= f.text_field :email %>
      </p> 
     <p>
        <%= f.label :phone %><br>
        <%= f.text_field :phone %>
      </p>
      <p>
        <%= f.label :state %><br>
        <%= f.text_field :state %>
      </p>
      <p>
        <%= f.label :country %> 
        <%= f.collection_select(:country, Country.all, :name, :name) %>
      </p>
      <p>
        <%= f.submit %>
      </p>
    <% end %>

这是我的控制器:

      class UserController < ApplicationController
    def index
        @users = User.all

    end

    def show
    @user = User.find(params[:id])
  end

    def new
        @user = User.new
    end


    def create
    @user = User.new(user_params)
        if @user.save
            redirect_to @user
        else
            render 'new'
        end 
    end

  def edit

    @user = User.find(params[:id])


  end

    def update
    #@user = User.find(params[:id])
        if @user.update(user_params)
        redirect_to @user
    else
      render 'edit'
    end
    end

    def destroy
    @user = User.find(params[:id])
    @user.destroy
      redirect_to user_index_path
  end

    private
    def user_params
        params.require(:user).permit(:name, :address, :email, :phone, :state, :country)
    end

end

由于我对Ruby还不熟悉,因此无法准确了解Ruby中的HTTP请求功能。


1
你需要将 <%= form_for :user, url: user_index_path do |f| %> 改为 <%= form_for @user, url: user_index_path do |f| %> - Pavan
现在我收到一个错误信息:"没有匹配的路由 [PATCH] '/user'"。 - Akshay
请粘贴您的“路由” - Pavan
你需要在更新操作中取消注释这一行代码:@user = User.find(params[:id]) - Pavan
1
方法索引与动作POST将始终调用控制器的创建方法,因此请进行我在答案中所做的更改。 - Vrushali Pawar
1个回答

15

用户/_form.html.erb

  <%= link_to 'Home', root_path %>
  <%= form_for @user do |f| %>
  <p>
  <%= f.label :name %><br>
  <%= f.text_field :name %>
  </p>

  <p>
  <%= f.label :address %><br>
  <%= f.text_area :address %>
  </p>
  <p>
  <%= f.label :email %><br>
  <%= f.text_field :email %>
  </p> 
  <p>
  <%= f.label :phone %><br>
  <%= f.text_field :phone %>
  </p>
  <p>
  <%= f.label :state %><br>
  <%= f.text_field :state %>
  </p>
  <p>
  <%= f.label :country %> 
  <%= f.collection_select(:country, Country.all, :name, :name) %>
  </p>
  <p>
  <%= f.submit %>
  </p>
  <% end %>

用户/新建.html.erb

<h2>Create new user</h2>
<%= render 'form' %>

用户/编辑.html.erb

<h2>Edit user</h2>
<%= render 'form' %>

用户控制器文件 users_controller.rb

class UsersController < ApplicationController
  before_filter :find_user, only: [:show, :edit, :update, :destroy]
  def index
    @users = User.all
  end

  def show    
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
    else
      render 'new'
    end 
  end

  def edit
  end

  def update
    if @user.update(user_params)
      redirect_to @user
    else
      render 'edit'
    end
  end

  def destroy
    @user.destroy
    redirect_to user_index_path
  end

  private
  def user_params
    params.require(:user).permit(:name, :address, :email, :phone, :state, :country)
  end

  def find_user
    @user = User.find(params[:id])
  end

end

当你在两个或更多方法中使用相同的视图代码时,应该创建一个相同视图代码的局部并在这些方法中进行渲染。这在Ruby on Rails中被称为DRY原则。


谢谢您让我知道这件事。我会确保以后不再重复代码。但是我仍然需要解决我的问题。 - Akshay
你现在有什么问题? - Vrushali Pawar
每当我执行“编辑”操作时,都会创建一个新条目,而不是编辑现有的条目。 - Akshay
我应该粘贴整个日志吗? - Akshay
开始GET "/user/40/edit",IP地址为127.0.0.1,时间为2015年6月1日10:53:49 +0530 处理UserController#edit的HTML请求 参数:{"id"=>"40"} [1m[36mUser Load (0.2ms)[0m [1mSELECT users.* FROM users WHERE users.id = 40 LIMIT 1[0m [1m[35mCountry Load (0.2ms)[0m SELECT countries.* FROM countries 渲染user/_form.html.erb(6.2ms) 在layouts/application中渲染user/edit.html.erb(7.5ms) 完成200 OK,用时36ms(视图:34.7ms | ActiveRecord:0.3ms) - Akshay
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/79287/discussion-between-akshay-and-user123。 - Akshay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接