【问题标题】:Ruby on Rails edit/update method is creating a new object instead of updatingRuby on Rails 编辑/更新方法是创建一个新对象而不是更新
【发布时间】:2012-06-19 19:20:15
【问题描述】:

我遇到了与这篇文章非常相似的问题(不太确定是否完全相同):

Edit method is creating new records, instead of just updating existing ones

^^您可能会注意到,没有发布解决方案。

我为我们大楼的网络设置了一张地图。它设置为地板=>开关,开关=>插孔。每个只嵌套一次。

问题出在我的切换编辑/更新方法中。当我单击开关的编辑按钮时,它会将我重定向到正确的 url (.../switch/1/edit),但我立即注意到表单不正确。而不是按钮说“更新开关”,它说“创建开关”,这正是发生的事情。创建了一个新开关,而不是更新我要更新的开关。

这里是相关代码。如果您想看其他内容,请告诉我。

...app/views/switches/_form.html.erb:

<%= form_for([@floor, @switch]) do |f| %>
  <% if @switch.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@switch.errors.count, "error") %> prohibited this switch from being saved:</h2>

      <ul>
      <% @switch.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

...app/controllers/switches_controller.rb:

class SwitchesController < ApplicationController

  def create
    @floor = Floor.find(params[:floor_id])
    @switch = @floor.switches.create(params[:switch])
    redirect_to(@floor)
  end

  def destroy
    @floor = Floor.find(params[:floor_id])
    @switch = @floor.switches.find(params[:id])
    @switch.destroy
    redirect_to(@floor)
  end

  def show
    @floor = Floor.find(params[:floor_id])
    @switch = @floor.switches.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => @switch }
    end
  end

  def edit
    @floor = Floor.find(params[:floor_id])
    @switch = @floor.switches.find(params[:id])
  end

  def update
    @floor = Floor.find(params[:id])
    @switch = @floor.switches.find(params[:id])

    respond_to do |format|
      if @switch.update_attributes(params[:switch])
        format.html { redirect_to @switch, :notice => 'Floor was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render :action => "edit" }
        format.json { render :json => @switch.errors, :status => :unprocessable_entity }
      end
    end
  end

end

谁能帮助弄清楚为什么它会使用 create 方法而不是 update 方法?谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 networking network-programming


    【解决方案1】:

    错误就在这里,表单总是为新开关构建的

    <%= form_for([@floor, @floor.switches.build]) do |f| %>
      <% @switch = @floor.switches.find(params[:id]) %>
    

    改成

    <%= form_for([@floor, @switch]) do |f| %>
    

    (并删除行)

    <% @switch = @floor.switches.find(params[:id]) %>
    

    我在控制器中没有看到new 动作,它看起来像

    def new
      @floor = Floor.find(params[:floor_id])
      @switch = @floor.switches.build
    end
    

    【讨论】:

    • 我尝试了您的第一个建议(更改了行,删除了第二个),现在我什至无法查看地板。 NilClass 的未定义方法 `model_name':Class 提取的源代码(第 1 行附近): 1:
    • 我也添加了新方法。
    • 您可能会在另一个控制器中为新的 swith 渲染表单,因为它以前在没有“新”操作的情况下工作。请检查哪个操作呈现表单并在此处添加@switch = @floor.switches.build。
    • 我相信我的操作“显示”会呈现表单,因为当我显示错误时它就在跟踪中。你是说我应该在那里尝试而不是'@switch = @floor.switches.find(params[:id])',或者除了?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 2015-07-26
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多