不合理的未定义方法“电子邮件”

Unreasonable undefined method `email'

我正在构建一个模仿Evernote的repo,并且我已经建立了模型与它们各自列之间的关系。其中,我是靠model User中的email这一列来识别用户的。

但是,当我尝试在 index.html.erb 中打印 <%= note.user.email %> 时,我收到“nil:NilClass 的未定义方法‘电子邮件’”错误。我不明白,我建立了有效的has_manybelongs_toemail也是一个实际的列。 note是controller中的实体变量@note派生出来的(其他字段有效的地方),我不明白哪个link是错误的。

这是架构的一部分

  create_table "users", force: :cascade do |t|
    t.string "nickname"
    t.string "password"
    t.string "email"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

这是模型用户的一部分

class User < ApplicationRecord
  validates :nickname, presence: true
  validates :email, presence: true
  validates :password, presence: true, confirmation: true

  before_create :encrypt_password

  has_many :notes

这是模型注释

class Note < ApplicationRecord
  validates :title, presence: true
  validates :content, presence: true

  default_scope { where(deleted_at: nil) }

  belongs_to :user
end

这是 NotesController 的一部分

  def index
    @notes = Note.includes(:user).order(id: :desc)
  end

这是index.html.erb

<table>
  <tr>
    <td>Author</td>
    <td>Title</td>
    <td>Actions</td>
  <% @notes.each do |note| %>
  <tr>
    <td>
      <%= note.user.email %>
    </td>
    <td>
      <%= link_to note.title, note_path(note) %>
    </td>
    <td>
      <%= link_to "TO EDIT", edit_note_path(note) %>
    </td>
    <td>
      <%= link_to "TO DELETE", note_path(note), method: 'delete', data: { confirm: "確定嗎?" } %>
    </td>
  </tr>
  <% end %>
</table>

undefined method `email' for nil:NilClass"

此错误意味着您正在 nilClass 对象上寻找方法 email,这意味着您的 note.user 为 nil。

Rails 找不到与该笔记相关的任何用户。您可以先检查您的 note 是否为 user.

您还应该检查您的 Note 模型中是否有一个列 user_id,它是使 belongs_to 关系正常工作所必需的。您可能在笔记迁移中做了类似的事情:

  create_table "notes", force: :cascade do |t|
    t.belongs_to :user
    ...
  end

如果您希望您的视图继续呈现并在注释没有任何用户时忽略错误,您可以这样做。

<% if note.user.present? %>
 <td>
   <%= note.user.email %>
 </td>
<% end %>

甚至使用 safe navigation operator 但它有其优点和缺点

<td>
  <%= note.user&.email %>
</td>