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>