Rails 不允许的参数

Rails Unpermitted Parameter

我有一个表单,其中包含一些用户可以在 post 上 select 的预构建标签。这些标签设置了 has_many through: 关系。一切似乎都在工作,但是当我保存时(post 确实保存了)控制器的保存方法中有一个 Unpermitted parameter: :tags

标签模型:

class Tag < ApplicationRecord
  has_many :post_tags
  has_many :posts, through: :post_tags
end

Post标签型号:

class PostTag < ApplicationRecord
  belongs_to :tag
  belongs_to :post
end

Post 型号:

class Post < ApplicationRecord
    ...
    has_many :post_tags
    has_many :tags, through: :post_tags

Post 控制器方法:

  def update
      # saves tags
      save_tags(@post, params[:post][:tags])

      # updates params (not sure if this is required but I thought that updating the tags might be causing problems for the save.
      params[:post][:tags] = @post.tags
      if @post.update(post_params)
        ... 
    end
  end

...

private 
  def post_params
    params.require(:post).permit(:name, :notes, tags: [])
  end

  def save_tags(post, tags)
    tags.each do |tag|
       # tag.to_i, is because the form loads tags as just the tag id.
       post.post_tags.build(tag: Tag.find_by(id: tag.to_i))
    end
  end

视图(标签是显示为按钮的复选框):

  <%= form.label :tags %>
    <div class="box">
    <% @tags.each do |tag| %>
      <div class="check-btn">
        <label>
          <%=  check_box_tag('dinner[tags][]', tag.id) %><span> <%= tag.name %></span>
      </label>
      </div>
      <% end %>
    </div>

再次保存,并且工作正常,但我想摆脱控制台中抛出的 Unpermitted parameter

你的整个解决方案很有创意,但非常多余。而是使用收集助手:

<%= form_with(model: @post) |f| %> 
  <%= f.collection_check_boxes :tag_ids, Tag.all, :id, :name %>
<% end %>

tags_ids= 是由 has_many :tags, through: :post_tags 创建的特殊 setter(它们是为所有 has_many 和 HABTM 协会创建的)。它需要一组 ID,并会自动 create/delete 为您加入行。

您在控制器中所要做的就是将白名单 post[tag_ids] 作为数组:

class PostsController < ApplicationController
  # ...

  def create
    @post = Post.new(post_params)
    if @post.save 
      redirect_to @post 
    else
      render :new
    end
  end

  def update
    if @post.update(post_params)
      redirect_to @post 
    else
      render :edit
    end
  end

  private 
  # ...

  def post_params
    params.require(:post)
          .permit(:name, :notes, tag_ids: [])
  end
end