Search code examples
ruby-on-railsrubyhidden-field

How to pass hidden field of user_id to comment?


I am trying to add a hidden field in comments/_form so the name of the user shows up in the comments section. Nothing I do works. I really want to use a hidden field so I know how to make it work.

User has many comments, and comments belongs to user.

This is what I currently have in comments/_form:

  <%= form_for([@place, @place.comments.build]) do |f| %>
     <%= hidden_field :user_id, :value => @user.id %>
  <p>
     <%= f.label :body %><br>
     <%= f.text_field :body %>
  </p>
  <p>
     <%= f.submit %>
  </p>
  <% end %>

This is what I currently have in _comment.html.erb Please note the comment.user.first_name.

This is the error I get undefined methodfirst_name' for nil:NilClass`:

 <p>
   <strong>Comment:</strong><br />
    <%= comment.user.first_name %> wrote:<br /><br>
    <%= comment.body %>
</p> 

<p>
  <%= link_to 'Destroy Comment', [comment.place, comment],
           method: :delete,
           data: { confirm: 'Are you sure?' } %>
 </p>

This is what I have in comments_controller

 class CommentsController < ApplicationController

   def create
     @place = Place.find(params[:place_id])
     @comment = @place.comments.create(comment_params)
     redirect_to place_path(@place)
   end

  def destroy
    @place = Place.find(params[:place_id])
    @comment = @place.comments.find(params[:id])
    @comment.destroy
   redirect_to place_path(@place)
 end

 private
   def comment_params
      params.require(:comment).permit(:body, :user_id)
   end
 end

This is what I have in the ApplicationController:

   helper_method :current_user 

   private 
     def current_user 
     @current_user ||= User.find(session[:user_id]) if session[:user_id]
    end 

Does anyone have any advice?

EDIT I'm adding in a couple more stuff for edification in case it helps.

Users controller

 class UsersController < ApplicationController
   def new
      @user = User.new
    end

   def create 
    @user = User.new(user_params)
      if @user.save 
      redirect_to root_url, :notice => "Signed Up!"
    else
      render "new"
    end
  end

 end

 private
   def user_params
      params.require(:user).permit(:email, :password, :password_confirmation)
   end

Sessions controller

  class SessionsController < ApplicationController
   def new
    end

   def create
      user = User.authenticate(params[:email], params[:password])
      if user
        session[:user_id] = user.id
        redirect_to places_path, :notice => "Logged in!"
      else
        flash.now.alert = "Invalid email or password"
       render "new"
      end
   end

   def destroy 
      session[:user_id] = nil
      redirect_to root_url, :notice => "Logged out!"
    end

  end

Places controller

 class PlacesController < ApplicationController

  def index 
     @places = Place.all 
   end 


  def new
    @place = Place.new
  end

  def create
    @place = Place.new(place_params)

    if @place.save 
       redirect_to @place
   else 
    render 'new'
  end
 end

 def show
   @place = Place.find(params[:id])
 end

def edit 
   @place = Place.find(params[:id])
 end 

 def update
   @place = Place.find(params[:id])
   if @article.update(place_params)
     redirect_to @place 
   else
     render 'edit'
  end
 end 

 def destroy 
   @place = Place.find(params[:id])
   @place.destroy 

   redirect_to places_path 
 end


end

 private 
  def place_params
    params.require(:place).permit(:name, :location)
  end

Solution

  • There is no need to send it through a hidden_field, instead, remove it.

    Rewrite your create method as follows:

    def create
      @place = Place.find(params[:place_id])
      @comment = @place.comments.create(comment_params)
      @comment.user = current_user
      if @comment.save
        redirect_to place_path(@place)
      else
        render "comments/_form"
      end
    end
    

    Hope it helps.