I'm trying to embed a Comment form to a rails Post show view and the only way I can get it to work is by passing this hidden field in the comment form:
<%= form.hidden_field :post_id, value: "#{params[:id]}" %>
Here is my Post show action:
def show
@comment = Comment.new
end
Here is the Comment create action:
def create
@user = current_user
@comment = @user.comments.build(comment_params)
end
I tried adding this to the Comment create action, but it still said the Post ID was missing:
def create
@user = current_user
@post = Post.find(params[:id])
@comment = @user.comments.build(comment_params).merge(post_id: @post.id)
end
I also tried adding the @post = Post.find(params[:id]) to the Post show action, thinking that if rails had that variable then the Comment create action would have access to @post.id).
The only thing that works is adding the post_id as a hidden field in the Comment form, but this seems dangerous because a malicious user could edit the html in the browser. I don't know why they would want to do this just to change the Post that the comment gets applied to, but it still seems not the right way to do this.
I don't want a "nested form" in the sense that the comment is something that is created via the post form.
It's really just a separate Comment form on the Post show page. I'm assuming this is a common thing in Rails, but having trouble figuring out the "correct" way to do this.
The Rails way to do this is is by declaring a nested resource:
This creates the route
POST /posts/:post_id/commentswhich connects the two resources in a RESTful way and makes it very transparent what is going on compared to placing the post id in the request body.You're thinking about the problem wrong. If users should only be able to comment on certain posts you need to enforce authorization on your server (such as by using Pundit or CanCanCan).
What is really bad is passing the current user id in hidden inputs as it makes it very easy for malicous users to create resources as another user.
You want to rely on the session storage instead as its encrypted and harder to tamper with.