【问题标题】:Time_ago_in_words is not workingTime_ago_in_words 不起作用
【发布时间】:2015-03-08 20:02:52
【问题描述】:

我遇到了一个奇怪的问题。在我的 Rails 应用程序中,执行:time_ago_in_words homework.created_at 返回错误:

undefined method `>' for nil:NilClass

上下文:

<h3 class="media-heading"><%= homework.title %></h3>
<p>Assigned <%= time_ago_in_words homework.created_at %> ago</p>

created_at 已定义,此迁移 t.timestamps null: false(是的,我已经运行了它),它在数据库中。

取出第二行时,表头起作用。

homework.created_at 返回:2015-03-08 13:45:11 -0500

追踪:

app/views/homeworks/_homework.html.erb:6:in `_app_views_homeworks__homework_html_erb__2140072314140949314_70221661493300'
app/views/welcome/home.html.erb:26:in `block in _app_views_welcome_home_html_erb__3498543795407979710_70221651392200'
app/views/welcome/home.html.erb:24:in `_app_views_welcome_home_html_erb__3498543795407979710_70221651392200'
app/controllers/welcome_controller.rb:7:in `index'

homework.created_at.to_time 错误:undefined methodto_time' for nil:NilClass`

【问题讨论】:

  • 能否提供完整的回溯?
  • @maxd 添加和更新!
  • 这只是回溯的一部分。有错误的 HTML 页面应该有链接 Full Trace。单击它,您将看到完整的回溯。
  • 在任何情况下都尝试在没有time_ago_in_words 帮助器的情况下输出homework.created_at。它不应该是零。检查一下。
  • this 行中的问题。似乎from_time 变量为零。这个 nil 可以出现在line 中。所以,尝试输出homework.created_at.to_time并检查一下。

标签: ruby-on-rails ruby ruby-on-rails-4 erb


【解决方案1】:

试试这个:

<%= time_ago_in_words(homework.created_at) unless homework.created_at.blank? %>

【讨论】:

  • Homework.created_at 总是返回正确的值(但不是文字)。似乎不是问题。
  • 等等...没关系,跳过这个问题...仍然不完美,但它有效。
【解决方案2】:

错误是说你在时间计算中有一个 nil 值:

undefined method `>' for nil:NilClass

您使用的方法比较两次:

  • from_time -- 这来自您的参数,即created_at
  • to_time -- 这是 Rails 自动使用 Time.now

请参阅 Rails 文档以获取 time_ago_in_words

错误显示在 Rails 堆栈中,您的 from_time 为 nil。

可能的原因是created_at 为零。

这个原因和你贴的第二个错误一致:

homework.created_at.to_time #=> 
undefined method to_time' for nil:NilClass`

也许您还没有保存对象,或者created_at 正在以某种方式消失,或者正在渲染的对象与您预期的不同?

如果您的目标是能够显示新对象或创建的对象,那么修复它的一种方法是添加if..then..else,例如:

<% if homework.created_at %> 
  <p>Assigned <%= time_ago_in_words homework.created_at %> ago</p>
<% else %>
  <p>Not Yet Assigned</p>
<% end %>

或者,如果您的目标是始终拥有created_at 时间,那么解决它的一种方法是显式设置时间(并准备好让 Rails 覆盖它),例如:

<% homework.created_at ||= Time.now %> 

或者,保存对象,如:

<% homework.save! %> 

(在我看来,最好在控制器中做save!,而不是视图)

编辑...您写道“我已经保存了对象(使用 RubyMine 进行验证),并且 created_at 不是 nil。”

这太令人惊讶了!您可以查看您正在渲染的对象是否与您想象的不同,例如添加此 ERB:

<!-- 
  Homework 
  id:<%= homework.id %>
  created_at:<%= homework.created_at %>
-->

或者这些类型的例外:

<% homework.id or raise "error in homework id" %>
<% homework.created_at or raise "error in homework created_at" %>

您可以绕过 time_ago_in_words 方法排除任何问题,直接进入更深层次的 Rails 方法:

<%= distance_of_time_in_words(homework.created_at, Time.now) %>

恕我直言,除此之外的任何错误都可能是由于意外(即 ERB 未以典型方式呈现,由于您的代码中超出此特定问题的一些意外)或缓存(即 ERB 正在呈现缓存的对象,或者以某种方式呈现与您预期不同的环境或对象)。

在你的 ERB 中试试这个:

<%= logger.debug("homework id:#{homework.id}" %>
<%= logger.debug("homework created_at:#{homework.created_at}" %>

然后查看您的日志文件,您可能会发现有问题,例如与您期望的不匹配的id 和/或nil,或created_at nil,或某种缓存问题,显示整个 ERB 文件有问题和/或未按您预期的方式运行。

另外,尝试检测 ERB 发送 homework 变量的错误。例如,如果您使用的控制器设置了@homework 变量,并使用具有典型控制器实例变量的上层 ERB,然后调用您的 ERB 部分,请尝试将其添加到上层 ERB,以便您可以验证控制器正在发送您想要的正确@homework

<%= logger.debug("@homework id:#{@homework.id}" %>
<%= logger.debug("@homework created_at:#{@homework.created_at}" %>

【讨论】:

  • 那我该如何解决呢?
  • 我已经保存了对象(使用RubyMine验证),created_at不为零。
  • 尝试在没有 RubyMine 的情况下检查它:&lt;%= homework.new_record? %&gt; &lt;%= homework.created_at %&gt;
  • 好像还是不行,想加入我们chat吗?
猜你喜欢
  • 1970-01-01
  • 2010-12-20
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
相关资源
最近更新 更多