我正在建立一个基本的聊天室网站,其中包含多个可供用户评论的聊天室。
我设法让我的消息/评论显示在每个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的更新版本。
答案 0 :(得分:2)
message.created_at
是nil
。您可以通过稍微更改代码来验证它:
<%= "#{time_ago_in_words(message.created_at || Time.now)} ago" %>
这将始终显示less than a minute ago
,因为message.created_at
是nil
。
<%= "#{time_ago_in_words(message.created_at)} ago" if message.created_at %>
这不会显示任何内容,因为message.created_at
是nil
。
我建议您使用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 %>
这将设置一个断点,如果message
或message.created_at
为nil
时将触发该断点,并允许您使用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
,并且所有内容都可以追溯到: