在rails 5中的数据透视表中保存关联

问题描述 投票:1回答:1

我有一个共同的多对多关系,这些是模型:

class Employee < ApplicationRecord
  has_many :related_professions
  has_many :professions, through: :related_professions

  accepts_nested_attributes_for :related_professions
end

class RelatedProfession < ApplicationRecord
  belongs_to :employee
  belongs_to :profession

  accepts_nested_attributes_for :profession
end

class Profession < ApplicationRecord
  has_many :related_professions
  has_many :employees ,through: :related_professions
end

我还有一个用于保存员工的表格。在这种形式中,我想以多个选择呈现所有职业,供用户根据需要选择。我希望当用户提交表单时,所有选定职业的ID都保存在RelatedProfession数据透视表中(它只有三列:id,employee_id,profession_id)。这是我的选择表单的一部分:

<div class="field">
  <%= form.label :professions %>
  <%= form.fields_for :related_professions do |rp| %>
    <%= rp.collection_select :profession_id, Profession.all, :id, :name, {}, {multiple: true} %>
  <% end %>
</div>

这是我的EmployeeController中允许参数的部分:

# Never trust parameters from the scary internet, only allow the white list through.
def employee_params
  params.require(:employee).permit(:name, related_professions_attributes: [:id, profession_id: [:id]])
end

第一个问题是,如果Employee没有任何已分配,则表单不会加载专业。我不得不手动将一个添加到数据库中,然后填充选择。

第二个问题是,当我尝试通过选择不同的专业来更新Employee(以及RelatedProfession数据透视表)时,它将无法工作,我收到此错误:

Related professions profession must exist

我知道在许可参数和表单中肯定存在错误,而这些参数和表单没有正确构建选择。

我很感激帮助。提前致谢。

ruby-on-rails ruby-on-rails-5
1个回答
2
投票

您不需要嵌套属性来通过关系创建has_many,您可以将它作为ID数组传递。

class Employee < ApplicationRecord
      has_many :related_professions
      has_many :professions, through: :related_professions
    end

    class RelatedProfession < ApplicationRecord
      belongs_to :employee
      belongs_to :profession
    end

    class Profession < ApplicationRecord
      has_many :related_professions
      has_many :employees ,through: :related_professions
    end

在形式上也只选择Professions的ID。

 <div class="field">
      <%= form.label :professions %>
        <%= rp.collection_select :profession_ids, Profession.all, :id, :name, {}, {multiple: true} %>
    </div>

改变强参数允许profession_ids作为数组。

def employee_params
  params.require(:employee).permit(:name, profession_ids: [])
end

希望这能解决你的问题。

© www.soinside.com 2019 - 2024. All rights reserved.