Hartl教程第9章“UsersController中的ArgumentError#edit”

时间:2015-05-22 16:30:26

标签: ruby-on-rails ruby

我是Ruby和Rails的新手,并且正在通过Hartl教程。我已经用Google搜索了这个错误,并提出了几个相似的内容(例如thisthis),但发布给他们的解决方案对我没有帮助。

根据教程说明,我的UsersController看起来像这样:

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

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

此时,showedit操作完全相同。 show操作正常(即显示有关@user的预期信息)。但是在edit链接后面会出现以下错误:

ArgumentError in UsersController#edit
First argument in form cannot contain nil or be empty
Extracted source (around line #432):

    else
        object      = record.is_a?(Array) ? record.last : record
        raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
        object_name = options[:as] || model_name_from_record_or_class(object).param_key
        apply_form_for_options!(record, object, options)
    end

错误页面稍微低一点,标题为“请求”,说

Parameters:
{"id"=>"1"}

...这似乎暗示参数正在传递,但由于某种原因,未从数据库中检索@user对象。

我尝试使用edit.html.erb交换show.html.erb的内容,结果是show页面现在正确显示了编辑表单,edit链接(现在包含show页面,以前工作正常)会抛出错误,因为它坚信@user对象是零。

非常感谢任何帮助/见解。

编辑:我真的认为我已将此消除作为可能的错误来源,但为了完整起见,这是edit表单代码:

<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user) do |f| %>
      <%= render 'shared/error_messages' %>

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

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

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

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

      <%= f.submit "Save changes", class: "btn btn-primary" %>
    <% end %>

    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="http://gravatar.com/emails" target="_blank">change</a>
    </div>
  </div>
</div>

编辑:我已尝试将表单代码的第6行更改为:

    <%= form_for(@user = User.find(params[:id])) do |f| %>

...和然后它正确呈现页面。虽然它没有回答更深层次的问题:“如果没有这个丑陋的黑客,它为什么会失效呢。”

2 个答案:

答案 0 :(得分:1)

视图正在交换,因为showedit路线存在差异。 show路由为user/:id,其中edit路由为user/:id/edit,其中包含表单。

http://guides.rubyonrails.org/routing.html(参见2.2 CRUD,动词和动作)

我会更加接近你的edit视图表格,甚至可以尝试从Hartl Listing 9.2中复制/粘贴,以找到一个特别难以捉摸的错字。

raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object 建议对象不是真实的(又名,它是nil)。

答案 1 :(得分:0)

嗯,我找到了答案,而且这一切都和你想象的一样愚蠢。我不小心读书。我没有意识到editupdate是两个独立的操作:上面第一个代码块中标记为def edit的控制器实际上标记为def update,我一直在阅读它为edit

非常感谢所有看过的人,特别是对于spectre6000,上面的链接让我更长时间地看一下控制器,并且真诚地为浪费你的时间而道歉。

从好的方面来说,我认为我在过去六个小时内对Rails的了解比在前两周完成本教程时更多。