You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 5多态Comment模型结合Devise新建评论参数始终校验不通过

Fixing "permitted => false" for Polymorphic Comment Model in Rails 5 + Devise

Hey there, let's work through why your Comment params are stuck as permitted => false—even using params.permit(:all) isn't fixing it because this is almost always about how your request parameters are structured, not the permit logic itself. Let's break this down step by step:

1. First, Check Your Request Params Structure

Start by looking at your Rails server logs when you submit the comment form. You should see something like this:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"abc123", "comment"=>{"title"=>"My Comment", "description"=>"Great post!", "commentable_id"=>"5", "commentable_type"=>"Post"}, "commit"=>"Create Comment"}

If you don't see a top-level comment key wrapping your form fields, that's the core problem. Rails' strong parameters rely on this nested structure, so params.permit(:all) would only allow top-level params (like utf8 or authenticity_token), not the actual comment data.

2. Fix Your Form to Include Polymorphic Fields

Your form_with call looks okay, but you're missing the hidden fields that link the comment to its parent commentable object. Add these to your _form.html.erb:

<%= form_with(model: comment, local: true) do |form| %>
  <%# Add hidden fields for polymorphic association %>
  <%= form.hidden_field :commentable_id, value: @commentable.id %>
  <%= form.hidden_field :commentable_type, value: @commentable.class.name %>

  <%# Your existing title/description fields %>
  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>

  <div class="field">
    <%= form.label :description %>
    <%= form.text_area :description %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

You'll also need to set @commentable in your controller's new action so the form knows which object the comment belongs to:

# comments_controller.rb
def new
  @commentable = find_commentable
  @comment = @commentable.comments.new
end

private
def find_commentable
  # Pulls the parent object from params (e.g., post_id, article_id)
  params.each do |name, value|
    if name =~ /(.+)_id$/
      return $1.classify.constantize.find(value)
    end
  end
  nil
end

3. Correct Your Strong Params Method

Even if you use params.permit(:all), you need to first target the nested comment hash. Replace your current params method with this:

# comments_controller.rb
private
def comment_params
  params.require(:comment).permit(:title, :description, :commentable_id, :commentable_type)
end

Here's why params.permit(:all) didn't work: it permits all top-level params, but your actual comment data is nested under comment. The require(:comment) ensures we're only working with that nested hash, then permit allows the specific fields we need.

4. Double-Check Devise Integration (If Needed)

If your Comment model belongs to a User (which makes sense with Devise), don't let the form submit a user_id (that's a security risk). Instead, set it manually in the create action:

def create
  @commentable = find_commentable
  @comment = @commentable.comments.new(comment_params)
  @comment.user = current_user # Link the comment to the logged-in user

  if @comment.save
    redirect_to @commentable, notice: 'Comment added successfully!'
  else
    render :new
  end
end

This way, you avoid exposing user_id in the form, and you ensure the comment is tied to the correct user.

Final Check

After making these changes, submit the form again and check your logs. You should see the comment params nested under comment, and the server won't log "Unpermitted parameters" anymore. If it still does, double-check that all fields you're submitting are included in the permit list.

内容的提问来源于stack exchange,提问作者Kieu Hua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:46:03