用户#new中的NoMethodError

时间:2011-09-23 21:35:55

标签: ruby-on-rails

我开始收到此错误:

NoMethodError: undefined method `has_key?' for nil:NilClass

在接近完成Hartl优秀的Rails教程的过程中。看起来我必须省略一个方法,但我知道在哪里,并且在Rails中调试是新手。

这是完整的堆栈跟踪:

activerecord (3.0.9) lib/active_record/attribute_methods/read.rb:80:in `id'
activerecord (3.0.9) lib/active_record/attribute_methods/primary_key.rb:9:in `to_key'
actionpack (3.0.9) lib/action_controller/record_identifier.rb:82:in `record_key_for_dom_id'
actionpack (3.0.9) lib/action_controller/record_identifier.rb:63:in `dom_id'
actionpack (3.0.9) lib/action_view/helpers/form_helper.rb:331:in `apply_form_for_options!'
actionpack (3.0.9) lib/action_view/helpers/form_helper.rb:313:in `form_for'
app/views/users/new.html.erb:3:in `_app_views_users_new_html_erb___834068491__620833808_0'
actionpack (3.0.9) lib/action_view/template.rb:135:in `send'
actionpack (3.0.9) lib/action_view/template.rb:135:in `render'
activesupport (3.0.9) lib/active_support/notifications.rb:54:in `instrument'
actionpack (3.0.9) lib/action_view/template.rb:127:in `render'
actionpack (3.0.9) lib/action_view/render/rendering.rb:59:in `_render_template'
activesupport (3.0.9) lib/active_support/notifications.rb:52:in `instrument'
activesupport (3.0.9) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.9) lib/active_support/notifications.rb:52:in `instrument'
actionpack (3.0.9) lib/action_view/render/rendering.rb:56:in `_render_template'
actionpack (3.0.9) lib/action_view/render/rendering.rb:26:in `render'
actionpack (3.0.9) lib/abstract_controller/rendering.rb:115:in `_render_template'
actionpack (3.0.9) lib/abstract_controller/rendering.rb:109:in `render_to_body'
actionpack (3.0.9) lib/action_controller/metal/renderers.rb:47:in `render_to_body'
actionpack (3.0.9) lib/action_controller/metal/compatibility.rb:55:in `render_to_body'
actionpack (3.0.9) lib/abstract_controller/rendering.rb:102:in `render_to_string'
actionpack (3.0.9) lib/abstract_controller/rendering.rb:93:in `render'
actionpack (3.0.9) lib/action_controller/metal/rendering.rb:17:in `render'
actionpack (3.0.9) lib/action_controller/metal/instrumentation.rb:40:in `render'
activesupport (3.0.9) lib/active_support/core_ext/benchmark.rb:5:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
activesupport (3.0.9) lib/active_support/core_ext/benchmark.rb:5:in `ms'
actionpack (3.0.9) lib/action_controller/metal/instrumentation.rb:40:in `render'
actionpack (3.0.9) lib/action_controller/metal/instrumentation.rb:78:in `cleanup_view_runtime'
activerecord (3.0.9) lib/active_record/railties/controller_runtime.rb:15:in `cleanup_view_runtime'
actionpack (3.0.9) lib/action_controller/metal/instrumentation.rb:39:in `render'
actionpack (3.0.9) lib/action_controller/metal/implicit_render.rb:10:in `default_render'
actionpack (3.0.9) lib/action_controller/metal/mime_responds.rb:261:in `retrieve_response_from_mimes'
actionpack (3.0.9) lib/action_controller/metal/mime_responds.rb:192:in `call'
actionpack (3.0.9) lib/action_controller/metal/mime_responds.rb:192:in `respond_to'
app/controllers/users_controller.rb:29:in `new'
actionpack (3.0.9) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.0.9) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.0.9) lib/abstract_controller/base.rb:150:in `process_action'
actionpack (3.0.9) lib/action_controller/metal/rendering.rb:11:in `process_action'
actionpack (3.0.9) lib/abstract_controller/callbacks.rb:18:in `process_action'
activesupport (3.0.9) lib/active_support/callbacks.rb:436:in `_run__434435962__process_action__943997142__callbacks'
activesupport (3.0.9) lib/active_support/callbacks.rb:410:in `send'
activesupport (3.0.9) lib/active_support/callbacks.rb:410:in `_run_process_action_callbacks'
activesupport (3.0.9) lib/active_support/callbacks.rb:94:in `send'
activesupport (3.0.9) lib/active_support/callbacks.rb:94:in `run_callbacks'
actionpack (3.0.9) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.0.9) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
activesupport (3.0.9) lib/active_support/notifications.rb:52:in `instrument'
activesupport (3.0.9) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.9) lib/active_support/notifications.rb:52:in `instrument'
actionpack (3.0.9) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.0.9) lib/action_controller/metal/rescue.rb:17:in `process_action'
actionpack (3.0.9) lib/abstract_controller/base.rb:119:in `process'
actionpack (3.0.9) lib/abstract_controller/rendering.rb:41:in `process'
actionpack (3.0.9) lib/action_controller/metal.rb:138:in `dispatch'
actionpack (3.0.9) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.0.9) lib/action_controller/metal.rb:178:in `action'
actionpack (3.0.9) lib/action_dispatch/routing/route_set.rb:62:in `call'
actionpack (3.0.9) lib/action_dispatch/routing/route_set.rb:62:in `dispatch'
actionpack (3.0.9) lib/action_dispatch/routing/route_set.rb:27:in `call'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:148:in `call'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:93:in `recognize'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:103:in `optimized_each'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:92:in `recognize'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:139:in `call'
actionpack (3.0.9) lib/action_dispatch/routing/route_set.rb:493:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/head.rb:14:in `call'
rack (1.2.3) lib/rack/methodoverride.rb:24:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/flash.rb:182:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/session/abstract_store.rb:149:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/cookies.rb:302:in `call'
activerecord (3.0.9) lib/active_record/query_cache.rb:32:in `call'
activerecord (3.0.9) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in `cache'
activerecord (3.0.9) lib/active_record/query_cache.rb:12:in `cache'
activerecord (3.0.9) lib/active_record/query_cache.rb:31:in `call'
activerecord (3.0.9) lib/active_record/connection_adapters/abstract/connection_pool.rb:354:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/callbacks.rb:46:in `call'
activesupport (3.0.9) lib/active_support/callbacks.rb:416:in `_run_call_callbacks'
actionpack (3.0.9) lib/action_dispatch/middleware/callbacks.rb:44:in `call'
rack (1.2.3) lib/rack/sendfile.rb:107:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/show_exceptions.rb:47:in `call'
railties (3.0.9) lib/rails/rack/logger.rb:13:in `call'
rack (1.2.3) lib/rack/runtime.rb:17:in `call'
activesupport (3.0.9) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.2.3) lib/rack/lock.rb:11:in `call'
rack (1.2.3) lib/rack/lock.rb:11:in `synchronize'
rack (1.2.3) lib/rack/lock.rb:11:in `call'
actionpack (3.0.9) lib/action_dispatch/middleware/static.rb:30:in `call'
railties (3.0.9) lib/rails/application.rb:168:in `call'
railties (3.0.9) lib/rails/application.rb:77:in `send'
railties (3.0.9) lib/rails/application.rb:77:in `method_missing'
railties (3.0.9) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.2.3) lib/rack/content_length.rb:13:in `call'
rack (1.2.3) lib/rack/handler/webrick.rb:52:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
rack (1.2.3) lib/rack/handler/webrick.rb:13:in `run'
rack (1.2.3) lib/rack/server.rb:217:in `start'
railties (3.0.9) lib/rails/commands/server.rb:65:in `start'
railties (3.0.9) lib/rails/commands.rb:30
railties (3.0.9) lib/rails/commands.rb:27:in `tap'
railties (3.0.9) lib/rails/commands.rb:27
script/rails:6:in `require'
script/rails:6

我可以看到错误是因为在登录过程中没有创建用户。 所以我进入了控制台,并试图创建一个用户;这是错误堆栈:

from script/rails:6irb(main):004:0> user=User.new
NoMethodError: undefined method `has_key?' for nil:NilClass
    from /usr/lib/ruby/gems/1.8/gems/activesupport-3.0.9/lib/active_support/whiny_nil.rb:48:in `method_missing'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.9/lib/active_record/base.rb:1512:in `has_attribute?'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.9/lib/active_record/base.rb:1672:in `inspect'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.9/lib/active_record/base.rb:1671:in `collect'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.9/lib/active_record/base.rb:1671:in `inspect'
    from /usr/lib/ruby/1.8/irb.rb:310:in `output_value'
    from /usr/lib/ruby/1.8/irb.rb:159:in `eval_input'
    from /usr/lib/ruby/1.8/irb.rb:271:in `signal_status'
    from /usr/lib/ruby/1.8/irb.rb:155:in `eval_input'
    from /usr/lib/ruby/1.8/irb.rb:154:in `eval_input'
    from /usr/lib/ruby/1.8/irb.rb:71:in `start'
    from /usr/lib/ruby/1.8/irb.rb:70:in `catch'
    from /usr/lib/ruby/1.8/irb.rb:70:in `start'
    from /usr/lib/ruby/gems/1.8/gems/railties-3.0.9/lib/rails/commands/console.rb:44:in `start'
    from /usr/lib/ruby/gems/1.8/gems/railties-3.0.9/lib/rails/commands/console.rb:8:in `start'
    from /usr/lib/ruby/gems/1.8/gems/railties-3.0.9/lib/rails/commands.rb:23
    from script/rails:6:in `require'

我正在使用Rails 3.0.9。如果有人能指出我正确的方向,肯定会很感激!

谢谢,

瑞克

补充帖子(9/27/11):

帮助我的评论者 -

是的,我已经迁移了我的数据库。

我在教程中的位置:我基本完成了教程,但与编写用户的方式不同,但使用的是脚手架而不是Hartl采用的增量方法。

这是users / new.html.erb:

<h1>New user</h1>

<%= form_for(@user) do |f| %>
  <div class="field">
    <%= f.label :firstname, "First Name" %><br />
    <%= f.text_field :firstname %>
  </div>
  <div class="field">
    <%= f.label :lastname, "Last Name" %><br />
    <%= f.text_field :lastname %>
  </div>
  <div class="field">
    <%= f.label :username %><br />
    <%= f.text_field :username %>
  </div>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </div>
  <div class="field">
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </div>
  <div class="field">
    <%= f.label :password_confirmation, "Confirmation" %><br />
    <%= f.password_field :password_confirmation %>
  </div>
  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>


<%= link_to 'Back', users_path %>

我认为导致我的错误的是,由于某种原因,模型不会创建用户对象;这就是为什么我得到'nil object'错误。

非常感谢任何帮助!

- 瑞克

2 个答案:

答案 0 :(得分:2)

欢迎使用Rails并调试Rails程序。

一些常规调试技巧。

  • 虽然nil对象确实有很多方法,但它显然不是ActiveRecord对象,因此没有has_key?方法。

  • 所以问题(正如你猜测的那样)应该返回一个ActiveRecord对象的方法是返回nil。

  • 接下来要弄明白为什么。由于您正在尝试创建ActiveRecord对象,因此该对象可能未通过其验证。保存前使用valid?进行检查。或者使用save!代替save如果保存操作不成功,save!方法将抛出错误。

  • 了解如何使用logging语句在调试时将日志消息发送到日志文件。

  • 您还可以使用交互式调试器。它可以设置,以便在浏览器的请求到达服务器中的特定代码行时调用它。 - 浏览器将使用沙漏,直到您在调试器中“继续”。

已添加调试验证

要调试验证,我使用了几种技术:

  • 不要试图使用调试器来执行验证 - 正如您所见,这是一个杯子的游戏。
  • 使用调试器调用AR对象上的savevalid?方法。然后,您可以检查对象或使用方法查看AR对象中包含的错误对象。错误对象通常会告诉您哪个验证失败。
  • 您还可以单独注释掉验证,直到找到给您带来问题的验证。
  • 您还可以使用调试器检查AR对象的属性,以查看属性值是否会通过验证。
  • Re:何时运行验证(正如您在评论中提到的那样)。请记住,默认情况下,验证将在创建和更新调用上运行。如果您希望仅在更新时检查单个验证(而不是在创建时),有几种方法可以执行此操作,请检查文档以进行单独验证。

还有更多关于验证的说法。如果您的特定验证失败并且您不理解失败的原因,请在SO中打开一个单独的问题。

Re:为什么必须在创建时传递验证,而不仅仅是更新 - 这是一项功能。它使您能够确保在数据库中仅创建有效对象。但你不必使用它。您可以将验证设置为仅在更新时处于活动状态。

验证是ActiveRecord的强大而复杂的部分。换句话说,它们可能很复杂,直到它们被理解为止。

答案 1 :(得分:2)

也许在您的用户模型上,您创建了一个覆盖ActiveRecord的初始化方法:Base

script/console

class User < ActiveRecord:Base

  def initialize

  end
end

User.new
=> NoMethodError: undefined method `has_key?' for nil:NilClass