0

How do I allow find_by_id to work so my comments will work with my posts that have slugs via friendly_id? Is there an alternative approach to doing this?

I have installed a Ruby gem called friendly_id and use it to create slugs on my blog posts. These blog posts have comments via polymorphic relationships. I have these conflicting methods that I think is the reason my comments don't work and rais the error:

undefined method 'comments' for nil:NilClass

Pointing to @comment = @commentable.comments.new comment_params in the create method in the comments controller.

In my Comment Model:

class Comment < ApplicationRecord
  belongs_to :commentable, polymorphic: true
  has_many :comments, as: :commentable, dependent: :destroy
end

In my Comments Controller:

class CommentsController < ApplicationController
  before_action :find_commentable

  def new
    @comment = Comment.new
  end

  def create
    @comment = @commentable.comments.new comment_params
    if @comment.save
      flash[:success] = "Thanks for sharing your thoughts!"
      redirect_back fallback_location: root_path
    else
      flash[:danger] = "There was an error posting your comment!"
      redirect_back fallback_location: root_path
    end
  end

  private

  def comment_params
    params.require(:comment).permit(:body, :email, :name)
  end

  def find_commentable
    @commentable = Comment.find_by_id(params[:comment_id]) if params[:comment_id]
    @commentable = Post.find_by_id(params[:post_id]) if params[:post_id]
  end
end

In my Post Model: has_many :comments, as: :commentable

My Routes:

resources :comments do
  resources :comments
end

My Server Logs:

app/controllers/comments_controller.rb:9:in `create'
Started POST "/posts/top-5-audio-industry-blogs/comments" for 127.0.0.1 at 2018-06-30 10:35:09 -0300
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[token]", "comment"=>{"body"=>"Hey, thanks for checking out the article! Any questions? Just ask me here and I'll be happy to help.", "name"=>"name", "email"=>"email", "nickname"=>""}, "commit"=>"Post Comment", "post_id"=>"top-5-audio-industry-blogs"}
Post Load (0.0ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = $1 ORDER BY "posts"."created_at" DESC LIMIT $2  [["id", 0], ["LIMIT", 1]]
Completed 500 Internal Server Error in 27ms (ActiveRecord: 6.0ms)



NoMethodError (undefined method `comment' for nil:NilClass):

It's the only thing that I can think of being the reason for this error as it worked without slugs. Thanks for any help in advance!

Jake
  • 1,086
  • 12
  • 38
  • 1
    Can you show the server logs? – Jagdeep Singh Jun 30 '18 at 13:44
  • @JagdeepSingh Thanks for asking, I updated my question with the logs. – Jake Jun 30 '18 at 14:04
  • 1
    Ok. Instead of doing `Post.find_by_id(params[:post_id])`, can you change it to `Post.friendly.find(params[:post_id])` and see if it works? – Jagdeep Singh Jun 30 '18 at 14:09
  • Wow, thanks this worked, I was a bit skeptical since my `commentable_id` accepts integers as a table value. Please create this as an answer and I'll be happy to accept it. – Jake Jun 30 '18 at 14:16

1 Answers1

2

As per the docs, you need to query the Comment and Post models a little differently since posts have slugs and comments do not. See below:

def find_commentable
  @commentable = if params[:comment_id]
                   Comment.find_by_id(params[:comment_id])
                 elsif params[:post_id]
                   Post.friendly.find(params[:post_id])
                 end

  # You should also handle the case if `@commentable` is `nil` after above.
  redirect_to somewhere, error: 'Post/Comment not found' unless @commentable
end
Jagdeep Singh
  • 4,880
  • 2
  • 17
  • 22
  • 1
    @Jake i think you edited the answer before i did, which overwrite your suggested edit. Can you do it again? – Jagdeep Singh Jun 30 '18 at 14:25
  • Thanks, I was just wondering if there was a major drawback of my use of `@commentable` for each `post` and `comment` instead of the `if / else` statement you provided? – Jake Jun 30 '18 at 14:29