Search code examples
ruby-on-railsbcryptcontrollers

User_id is not passed to secondary controller


I'm building a fairly basic app in Rails, making use of two main controllers, users and comments. I'm using Bcrypt and has secure_password for user encryption, and nested resources so that user has_many comments and comments belongs_to user.

When I try to save a new comment, the error message I receive is the following: unknown attribute 'user_id' for Comment. It seems that the user_id is not passed to the controller, although this should be done using current_user as defined in the comments controllers - which currently look like this:

def new
    @user = current_user
    @comment = Comment.new
    @comment.save
end

def create
    @user = current_user
    @comment = @user.comments.new(comment_params)
    @comment.save
    redirect_to user_comments_path, notice: "Thank you for your comment!"
end

......

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

When I try to save the comments I'm logged in, so I'm not sure why the user_id would not be passed to the controller. I would very much appreciate some advice, thank you.


Solution

  • When I try to save a new comment, the error message I receive is the following: "unknown attribute 'user_id' for Comment.

    When using the belongs_to association association you have to actually add column to the table to store the foreign key.

    You can generate the migration with:

    rails g migration add_user_id_to_comments user:belongs_to
    

    Then migrate with rails db:migrate.

    Your controller has numerous issues as well:

    def new
      @comment = current_user.comments.new
      # never save in new method!
    end
    
    def create
      @comment = current_user.comments.new(comment_params)
      # you always have to check if save/update was successful
      if comment.save
        redirect_to user_comments_path, notice: "Thank you for your comment!"
      else
        render :new
      end
    end
    

    There is no need to save current_user to a separate instance variable as you should be memoizing it.

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