Reputation: 277
Unsure what to do at this point, I've followed a tutorial but can't get even the comments to post currently. They work just fine if I take all relations/mentions of commentable out of the models. But I would like to build a functionality for a nested commenting system where it's possible to comment on a comment. Here are all the pertinent files + errors.
New comment form located inside comments new.html.erb page
<div class='form-signin col-md-6 offset-md-3'>
<%= form_with url: post_comments_path, scope: "comment", local:true do |form| %>
<div class="form-group">
<%= form.label :body %>
<%= form.text_area :body, :class => "form-control-lg" %>
</div>
<div class="form-group">
<%= form.hidden_field :user_id, :value =>current_user.id %>
<%= form.hidden_field :post_id, :value => @post.id %>
<%= form.hidden_field :commentable_id, :value => @comment.id %>
<%= form.hidden_field :commentable, :value => @comment.body %>
</div>
<%= form.submit %>
<% end %>
</div>
Comments model
class Comment < ApplicationRecord
belongs_to :post
belongs_to :user
belongs_to :commentable, polymorphic: true
has_many :comments, as: :commentable
paginates_per 5
end
Comments controller:
def create
@post = Post.find(params["post_id"])
user_id = comment_params["comment"]["user_id"]
body = comment_params["comment"]["body"]
@comment = Comment.new(post_id: @post.id, user_id: user_id, body: body )
if @comment.save
redirect_to post_path(@post), method: :patch, notice: 'Reply successfully created.'
else
redirect_to post_path(@post), notice: @comment.errors.messages
end
end
def comment_params
params.permit(:post_id, comment: [:user_id, :body] )
end
The error I get when I try to post a comment currently:
Server Logs:
Started GET "/posts/1" for 127.0.0.1 at 2018-09-27 16:33:56 -0400
Processing by PostsController#show as HTML
Parameters: {"id"=>"1"}
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/controllers/posts_controller.rb:40
Rendering posts/show.html.erb within layouts/application
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 143], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:21
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 19], ["LIMIT", 1]]
↳ app/views/posts/show.html.erb:45
(0.4ms) SELECT COUNT(*) FROM "comments" WHERE "comments"."commentable_id" = $1 AND "comments"."commentable_type" = $2 [["commentable_id", 1], ["commentable_type", "Post"]]
↳ app/views/posts/show.html.erb:49
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 19], ["LIMIT", 1]]
↳ app/views/posts/show.html.erb:49
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 19], ["LIMIT", 1]]
↳ app/views/posts/show.html.erb:54
Comment Load (0.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."commentable_id" = $1 AND "comments"."commentable_type" = $2 [["commentable_id", 1], ["commentable_type", "Post"]]
↳ app/views/posts/show.html.erb:71
Rendered posts/show.html.erb within layouts/application (11.8ms)
Completed 200 OK in 49ms (Views: 42.8ms | ActiveRecord: 1.7ms)
Like I said earlier, the comments work just fine without the commentable system, but would like to add this functionality if possible with my current structure. Do not have any gems installed for this function.
Upvotes: 0
Views: 47
Reputation: 82
First of all you have a security flaw in the above code: <%= form.hidden_field :user_id, :value =>current_user.id %>
this is not needed. Please take the current user from the session instead in the controller. With the above code one can change the user id in the view and submit it so the comment will be attached to another user.
The next thing I see is the following:
<%= form.hidden_field :commentable, :value => @comment.body %>
the commentable
is your relation why you assign the comment's body there? that should be commentable_type
and the value should be the class name of the comment thus:
<%= form.hidden_field :commentable_type, :value => @comment.class.name %>
In your controller you do not assign a commentable so the validation fails since a commentable is required.
Moreover since you decided to make the comment polymorphic you don't need a reference to the post anymore. You only need to keep a reference to the commentable.
GoRails should have a great example I really like the instructor (Chris Oliver). You can check it here: https://gorails.com/episodes/comments-with-polymorphic-associations
Please follow the tutorial and make sure you adapt your code accordingly. Hope that helps.
Upvotes: 0