Home > Net >  comment.user.username not working on show.html.erb
comment.user.username not working on show.html.erb

Time:04-17

i'mtrying a simple feature where a user can comment on inquest post , but comment .user.username is not working ,it's rendering comment.user but does not support user attributes

create_table "comments", force: :cascade do |t|
t.string "content"
t.integer "inquest_id"
t.integer "user_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["inquest_id"], name: "index_comments_on_inquest_id"
t.index ["user_id"], name: "index_comments_on_user_id"
end

comment_model

class Comment < ApplicationRecord
belongs_to :inquest 
belongs_to :user
end

user_model is simple with has many comments association

comments create method of controller

  def create

@comment = Comment.new(comment_params)

pp comment_params
@inquest = Inquest.find(params[:inquest_id])
@comment = Comment.new(comment_params)
@comment.inquest = @inquest
@comment.user = current_user
respond_to do |format|
  if @comment.save
    format.js do
      @inquest = Inquest.find(params[:inquest_id])

    end
  else
    format.html { render :new, status: :unprocessable_entity }
    format.json { render json: @comment.errors, status: :unprocessable_entity }
  end
end
end

I'm rendering comments in inquest's show.html.erb

Showing /Users/zunairaihsan/Desktop/fyp_ed_bolt/app/views/inquests/show.html.erb 
   where line #123 raised:

 undefined method `user_name' for nil:NilClass

I've tried most of the ways possible , but it's not working.please let me know where I'm wrong

CodePudding user response:

I assume, in inquests/show.html.erb you're displaying multiple comments, something like

<%= @inquest.comments.each do |comment| %>
  <%= comment.user.user_name %>
  <%= comment.content %>
<% end %>

Many comments will render without issue. Comment model and database doesn't allow user_id to be nil.

But looks like one comment's user_id doesn't have a corresponding id in users table. When you try to figure out what's going on and remove user_name

<%= @inquest.comments.each do |comment| %>
  <%= comment.user %>
  <%= comment.content %>
<% end %>

Sneaky broken comment probably doesn't show you anything, comment.user is nil, and because you have no validation on comment.content it could also be nil.

First, get rid of comments without user to verify this is the issue:

# this is fast enough for a few thousand comments
>> Comment.find_each { |comment| comment.destroy unless comment.user }

After this inquests/show.html.erb should be working.

To make sure this doesn't happen again:

class User
  # this will delete all `user.comments` when you destroy `user`
  has_many :comments, dependent: :destroy

  # ...
end

To really make sure this doesn't happen again:

class CreateComment < ActiveRecord::Migration[7.0]
  def change
    create_table :comments do |t|
      t.references :user, null: false, foreign_key: true
      
      # ...
    end
  end
end

With foreign_key constraint, your database will not let you destroy a user if they have comments. This works in tandem with dependent: :destroy. If you delete a user and rails automatically destroys all user.comments, then database will not complain.

Probably do the same for inquest as well if it's not optional.

Also comments without content are not really comments:

class Comment < ApplicationRecord
  belongs_to :inquest 
  belongs_to :user

  validates :content, presence: true
end

CodePudding user response:

On line 123 of .../fyp_ed_bolt/app/views/inquests/show.html.erb, the object comment.user is nil, so there is no one method user_name for a nil object.

  • Related