nil不能转换为时间值

时间:2018-09-30 22:45:10

标签: html ruby-on-rails ruby

我正在建立一个基本的聊天室网站,其中包含多个可供用户评论的聊天室。

我设法让我的消息/评论显示在每个Room.show页面上,但是当我进入

<p><%= message.user.name if message.user %> <small><em><%= "#{time_ago_in_words(message.created_at)} ago" %></em></small></p>

我收到的nil无法转换为时间值错误。另外,我无法显示用户名。它只是空白。

这是我的Room.show.html.erb中记录错误的部分

<% @message.each do |message| %>
  <div class="row">
    <p><%= message.user.name if message.user %> <small><em><%= "#{time_ago_in_words(message.created_at)} ago" %></em></small></p>
    <p><%= message.body %></p>
  </div>
<% end %>

这是我的消息控制器

    def show
      @rooms = Room.all
      @message = @room.message
    end

这是我的路线文件

    Rails.application.routes.draw do
        devise_for :users
        #resources :messages
        resources :users
        resources :rooms do
          resources :messages
        end

        root 'rooms#index'

    end

Message.rb

        class Message < ApplicationRecord
           belongs_to :user
           belongs_to :room
        end

还有room.rb

          class Room < ApplicationRecord
             has_many :message
          end

使用Rails的更新版本。

1 个答案:

答案 0 :(得分:2)

message.created_atnil。您可以通过稍微更改代码来验证它:

<%= "#{time_ago_in_words(message.created_at || Time.now)} ago" %>

这将始终显示less than a minute ago,因为message.created_atnil

<%= "#{time_ago_in_words(message.created_at)} ago" if message.created_at %>

这不会显示任何内容,因为message.created_atnil

我建议您使用pry之类的调试库来帮助您解决此问题。您可以执行以下操作:

<% @message.each do |message| %>
  <div class="row">
    <% binding.pry unless message && message.created_at %>
    <p><%= message.user.name if message.user %> <small><em><%= "#{time_ago_in_words(message.created_at)} ago" %></em></small></p>
    <p><%= message.body %></p>
  </div>
<% end %>

这将设置一个断点,如果messagemessage.created_atnil时将触发该断点,并允许您使用Rails控制台检查变量以缩小问题范围。

就像其他人提到的那样,您需要确保正确构建了模型:

class Room < ApplicationRecord
  has_many :messages
end

您还应该检查schema.rb,以确保Message模型具有以下特点:

t.datetime "created_at", null: false
t.index ["room_id"], name: "index_messages_on_room_id"

第一个是必需的,因为没有message.created_at根本不会存在,而第二个对于两个模型之间的关联是必需的。

您的控制器代码没有任何意义,我假设您手动将其输入到您的问题中,而不是复制并粘贴它。您将@rooms定义为ActiveRecord::Relation集合对象,但是调用了@room.message。如果您的意思是@rooms.message,那将不起作用,因为您正试图在集合上调用实例方法。我不确定您在这里的意思,因为代码没有意义。

此外,您没有实现clean CRUD solution。您的Messages控制器的show方法应该用于呈现单个Message对象,而不用于呈现房间消息的集合。

通常,您键入的代码,结构和示例存在许多问题。不过至少,在尝试调用message.created_at之前,必须确保nil不是time_ago_in_words,并且所有内容都可以追溯到:

  • 确保模型正确形成并相互关联
  • 确保您的控制器正在提取真实对象
  • 确保您的视图适当地迭代了这些真实对象