html - nil 无法转换为 Time 值

标签 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 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_atnil。您可以通过稍微更改代码来验证它:

<%= "#{time_ago_in_words(message.created_at || Time.now)} 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 将根本不存在,第二个是两个模型之间关联所必需的。

您的 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/

相关文章:

javascript - 将 jQuery 用于 Dom 大纲。

ruby-on-rails - 找不到 gem 内的 Rake 任务

ruby - 在 ruby​​ 中使用组合

jquery - 显示带有 JQuery 自动完成建议的下拉列表

html - No provider for ControlContainer 和 No provider for ControlContainer

html - 在 Node.js 中使用 XPath 解析 HTML/XML

mysql - 如何将 sql 时间戳值插入到 Rails 中的日期时间类型?

javascript - Rails Assets 管道

ruby-on-rails - 当使用 "find_all_by"时,为什么使用 :order => :title rather than :order => title

Ruby:查找最近修改的文件