【问题标题】:Undefined method `model_name' for NilClass:ClassNilClass:Class 的未定义方法“model_name”
【发布时间】:2011-12-30 16:45:06
【问题描述】:

Ruby 3.1 Rails 1.9.2 绝对新手

当我尝试在应用程序中编辑现有广告时,问题就开始了。

我收到“NilClass:Class 的未定义方法 `model_name'”错误。以下信息可能会提供有关问题所在的线索。我花了几个小时试图弄清楚它无济于事。

Routes.rb

match 'ads/:id/edit' => 'ads#edit'
match 'ads/:id/update' => 'ads#update'
match 'ads/' => 'ads#index'
match 'ads/new' => 'ads#new'
match 'ads/create' => 'ads#create

控制器中的条目

def edit
  @ad=Ad.find(params[:id])
end

def update
        @ad=Ad.find(params[:id])
        @ad.update_attributes(params[:id])
        redirect_to "/ads/#{@ad.id}"
end

查看:

<%= form_for(@ad,:url=>{:action=>'update'}) do |f| %>
<p><b>Name</b><br /><%= f.text_field :name %></p>
<p><b>Description</b><br /><%= f.text_area :description, rows: 10 %></p> 
<p><b>Price</b><br /><%= f.text_field :price %></p>
<p><b>Seller</b><br /><%= f.text_field :seller_id %></p>
<p><b>E-mail</b><br /><%= f.text_field :email %></p>
<p><b>Img url</b><br /><%= f.text_field :img_url %></p>
<p><%= f.submit "Update" %></p>
<% end %>

任何帮助将不胜感激。 谢谢。

【问题讨论】:

  • 不相关,但我建议仍然使用 Ruby 1.8 样式的哈希(即:rows =&gt; 10)而不是 1.9 样式的(rows: 10),除非您知道此应用程序将永远运行在使用 Ruby 1.9.2 的环境。否则,您将不得不返回并更改应用程序中每个哈希的样式。

标签: ruby-on-rails


【解决方案1】:

有几点:

@mu-is-too-short 的更新方法示例是正确的。您应该将属性哈希 (params[:ad]) 发送到 @ad 对象,而不是参数 params[:id]

明确写出这样的路线可能会变得非常混乱。您可以将您在routes.rb 文件中写入的所有内容替换为:

resources :ads

这将使您能够使用诸如

之类的东西
redirect_to ad_path(@ad)

代替

redirect_to "/ads/#{@ad.id}"

此外,您的表单将更易于管理且不易出错,因为您可以说:

<%= form_for @ad do |f| %>
  <p><b>Name</b><br /><%= f.text_field :name %></p>
  <p><b>Description</b><br /><%= f.text_area :description, rows: 10 %></p> 
  <p><b>Price</b><br /><%= f.text_field :price %></p>
  <p><b>Seller</b><br /><%= f.text_field :seller_id %></p>
  <p><b>E-mail</b><br /><%= f.text_field :email %></p>
  <p><b>Img url</b><br /><%= f.text_field :img_url %></p>
  <p><%= f.submit "Update" %></p>
<% end %>

顺便说一句,我建议对 HTML 语义进行一些研究。看起来更像这样的表单更易于维护和设置样式,并且更易于访问:

<%= form_for @ad do |f| %>
  <fieldset>
    <%= f.label :name %>
    <%= f.text_field :name %>
  </fieldset>

  <fieldset>
    <%= f.label :description %>
    <%= f.text_area :description, :rows => 10 %>
  </fieldset>

  <!-- etc -->

  <fieldset>
    <%= f.submit 'Update' %>
  </fieldset>
<% end %>

如果您还没有阅读过,我强烈建议您阅读所有 Rails Guides,尤其是 guide on routing

【讨论】:

  • 1.非常感谢,很多有用的提示。因为我是一个完全的新手,所以我不完全理解为什么将属性哈希 (params[:ad]) 发送到 @ad 对象不起作用。最重要的是 - 您能否给我一个最有可能在这种情况下用于更新方法的代码示例?我应该用什么代替这段代码? @ad.update_attributes(params[:id])
  • 2.愚蠢的问题。我认为某些代码可能会导致我提到的错误。所以我只是注释掉了控制器代码中的整个“更新”部分,希望它至少能让我进入编辑页面 - 但是,当我点击“编辑”链接并进入编辑页面时,我仍然收到同样的错误。
  • 1.您应该将属性哈希发送到@ad。您当前的方法发送一个整数:params[:id],它是数据库中@adid 列的值。 params[:ad] 保存表单数据。你应该使用@ad.update_attributes(params[:ad])
  • 2.您可以发布错误的整个输出吗? Rails 应该会告诉你它在哪里遇到了麻烦的代码。我将首先按照我的建议更改routes.rb,然后只使用form_for @ad do |f|
  • 2. [我将从更改 routes.rb 开始] ***** 立即这样做,但没有帮助。我还将 html 语义更改为您建议的语义。我还使用了 form_for @ad do |f|我仍然遇到同样的错误。
【解决方案2】:

我认为您的 update 控制器方法很混乱。将 ID 传递给 update_attributes 不会让您到达您想去的任何地方,您想将一些属性传递给该方法,并且这些属性应该在 params[:ad] 中,一些错误处理也可能很好:

def update
    @ad = Ad.find(params[:id])
    if(@ad.update_attributes(params[:ad]))
        # It worked, redirect to the show action.
    else
        # It didn't work, make them do it again.
    end
end

【讨论】:

  • "将 ID 传递给 update_attributes 不会让您到达您想去的任何地方" ----如果您能解释为什么它不能让我到达任何地方,我将不胜感激? (我面临的问题是我使用的是我真正喜欢的书——Head First Rails——但它使用了以前版本的 rails。我提到的例子是直接取自那本书(@ad.update_attributes(params[ :id])) 所以我猜是版本差异让这一切都混淆了)
  • @Elijah:params[:id] 是一个 ID 号,但 update_attributes 想要一个属性名称及其新值的哈希值。你需要一本最新的书。
  • 如果您正在使用 Rails 3,我强烈建议您不要使用 Rails 2 书籍。有很多差异和不兼容之处,您会错过大部分使 Rails 3 成为改进。
  • @mu 太短了:我同意,我坚持那本书的唯一原因是我还没有看到任何其他真正解释清楚的书。我还有很多其他的书正在阅读——其中一本是用于 ruby​​ 3.1 的敏捷 Web 开发。只是我也需要一些基础知识。 ((我是一名拥有 12 年经验的网络管理员,但我在编程方面所做的唯一一件事就是一点 linux 脚本编写——所以我需要一本真正彻底触及这些基础知识的书)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多