我正在构建一个基本的聊天室网站,其中包含多个用户可以发表评论的聊天室。
我设法让我的消息/评论显示在每个 Room.show 页面上,但是当我进入时
<p><%= message.user.name if message.user %> <small><em><%= "#{time_ago_in_words(message.created_at)} ago" %></em></small></p>
我收到一个 nil can't be converted to a Time value 错误。另外,我无法显示用户名。它只是注册空白。
这是我的 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 %>
这是我的消息 Controller
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
消息.rb
class Message < ApplicationRecord
belongs_to :user
belongs_to :room
end
还有room.rb
class Room < ApplicationRecord
has_many :message
end
使用更新版本的 rails。
最佳答案
message.created_at
为 nil
。您可以通过稍微更改代码来验证它:
<%= "#{time_ago_in_words(message.created_at || Time.now)} 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
将根本不存在,第二个是两个模型之间关联所必需的。
您的 Controller 代码没有任何意义,我假设您是将其手动输入到您的问题中,而不是复制和粘贴。您将 @rooms
定义为 ActiveRecord::Relation
集合对象,但您调用了 @room.message
。如果您的意思是 @rooms.message
那么这将不起作用,因为您正试图在集合上调用实例方法。我不确定你在这里的意思,因为代码没有意义。
此外,您没有实现 clean CRUD solution .您的 Messages
Controller 的 show
方法应该用于呈现单个 Message
对象,而不是用于呈现房间消息的集合。
总的来说,你打出来的代码、结构、例子都有很多问题。至少,在尝试调用 time_ago_in_words
之前,您必须确保 message.created_at
不是 nil
,并且所有的跟踪都可以追溯到:
- 确保您的模型正确形成并相互关联
- 确保您的 Controller 正在获取真实对象
- 确保您的 View 适本地迭代这些真实对象
关于html - nil 无法转换为 Time 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52582772/