Home > Enterprise >  Unreasonable undefined method `email'
Unreasonable undefined method `email'

Time:04-28

I am building a repo that imitates Evernote, and I have established the relationship between the models and their respective columns. Among them, I rely on the column email in the model User to identify the user.

However, when I try to print <%= note.user.email %> in index.html.erb, I get an "undefined method `email' for nil:NilClass" error. I don't understand, I have established valid has_many and belongs_to, and email is also an actual column. note is derived from the entity variable @note in the controller (where other fields are valid), I don't understand which link is wrong.

This is part of the schema

  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

This is part of model User

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

  before_create :encrypt_password

  has_many :notes

This is model Note

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

  default_scope { where(deleted_at: nil) }

  belongs_to :user
end

This is part of NotesController

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

this is 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>

CodePudding user response:

undefined method `email' for nil:NilClass"

This error means you are looking for the method email on a nilClass object which mean your note.user is nil.

Rails can't find any user related to the note. You can first check if your note as a user.

Also you should check if you have a column user_id in your Note model it's needed for making the belongs_to relationship working. You probably did something like this in your note migration:

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

If you want your view to keep rendering and ignore the error if a note doesn't have any user you can do like this.

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

or even using the safe navigation operator but it has its pros & cons

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