通过 Rails 中的多个 select 加入 table 的不允许的参数

Unpermitted parameter for join table via multiple select in Rails

我 运行 在 Rails 5 中嵌套参数时出错:Unpermitted parameter: specialties

我有一个 Expertise 模型:

class Expertise < ApplicationRecord
    has_many :buckets, through: :specialties
    has_many :specialties   
end

桶模型:

class Bucket < ApplicationRecord
    has_many :expertises, through: :specialties
    has_many :specialties
end

还有一个专业模型:

class Specialty < ApplicationRecord
    belongs_to :expertise
    belongs_to :bucket
end

我试图让用户编辑他或她的专长并调整与他们相关的专长。 @buckets是controller传入的,目前的形式是这样的:

<%= form_for(expertise) do |f| %>
    <%= f.fields_for :specialties do |s| %>
        <%= s.collection_select :bucket_ids, @buckets, :id, :name, {}, { multiple: true, class: "input" } %>
    <% end %>
<% end %>

我的表格基于 this answer

这是来自 ExpertisesController 的相关片段:

def expertise_params
    params.require(:expertise).permit(:user_id, :name, :rating, :description, specialties_attributes: [:id, :expertise_id, :bucket_id, :_destroy, bucket_ids: []])
end

下面是传入的参数:

Parameters: {"expertise"=>{"specialties"=>{"bucket_ids"=>["", "1"]}, "description"=>""}, "id"=>"97"}

specialties应该是一个数组吧?我不确定该怎么做。

目的是使用户能够轻松地从可用的存储桶 (@buckets) select 中打开或关闭他或她的专业技能。所以假设有 5 个桶可用,用户将只能切换 on/off 5 个可能的专业知识。

情况:专业知识 has_many 通过专业知识分类并且您想更新特定专业知识的某些知识分类状态。所以你可以这样做:

class ExpertisesController < ApplicationController
  def your_action
    @expertise = Expertise.find params[:id]
    bucket_ids = params[:expertise][:specialties][:bucket_ids]
    @expertise.specialties.where(id: bucket_ids).update(status: :on)
  end
end

Unpermitted parameter: specialties

您没有设置 accept_nested_attributes_for 并出现该错误

class Expertise < ApplicationRecord
  has_many :specialties
  has_many :buckets, through: :specialties
  accepts_nested_attributes_for :specialties
end

When I try that, the nested fields_for form doesn't return any specialties and so the HTML element is empty. Then, when I try to use @expertise.specialties.build, I get undefined method bucket_ids for Specialty because bucket_ids isn't actually an attribute, but bucket_id is. Worth keeping in mind that the User needs to be able to toggle multiple Specialties, each of which is tied to a Bucket (via a bucket_id), and from what I've ready I'm supposed to use bucket_ids (the plural) there

您不需要 复数形式 (_ids) 只是因为要接受多个值。只需保留 bucket_id 即可接受多个值。并且不要忘记在控制器中构建关联模型

定义新 @expertise = Expertise.new @expertise.specialties.build 结尾

的形式中将bucket_ids更改为bucket_id

<%= s.collection_select :bucket_id, @buckets, :id, :name, {}, { multiple: true, class: "input" } %>

最后,expertise_params应该是

def expertise_params
  params.require(:expertise).permit(:user_id, :name, :rating, :description, specialties_attributes: [:id, :expertise_id, :_destroy, bucket_id: []])
end

更新:

好的,经过一些研究,它看起来应该是 bucket_ids,但是 bucket_ids 应该 允许作为 expertise 的属性.检查此 post 并相应地调整 formexpertise_params。您也不需要 accept_nested_attributes_for