Rails has_many:通过不保存关系或保存损坏的关系

时间:2014-11-13 00:40:23

标签: ruby-on-rails forms activerecord model associations

我有模特:

class Agency < ActiveRecord::Base
  has_many :specializations
  has_many :cruise_lines, through: :specializations
end

class CruiseLine < ActiveRecord::Base
  has_many :specializations
  has_many :agencies, through: :specializations
end

class Specialization < ActiveRecord::Base
  belongs_to :agency, inverse_of: :specializations
  belongs_to :cruise_line, inverse_of: :specializations
end

在我看来,我在HAML

中的表格中有复选框
= agency.collection_check_boxes(:cruise_line_ids, CruiseLine.all, :id, :name) do |specialization|
  .checkbox
    = specialization.label do
      = specialization.check_box type: "checkbox"
      = specialization.object.name

这会生成有效的HTML结尾(它正确地显示已连接到当前代理商的邮轮 - 如果我直接向DB添加所需的条目)

<div class='checkbox'>
    <label for="agency_cruise_line_ids_27"><input type="checkbox" value="27" name="agency[cruise_line_ids][]" id="agency_cruise_line_ids_27" />
        TransOcean Kreuzfahrten
    </label>
</div>
<input type="hidden" name="agency[cruise_line_ids][]" value="" />

在日志中保存表单时,我会看到这样的参数Parameters: {"utf8"=>"✓", "authenticity_token"=>"some-long-token", "agency"=>{"name"=>"Test agency", "website"=>"http://www.bla-bla.com", "description"=>"", "booking_email"=>"", "booking_phone"=>"", "optional_booking_phone"=>"", "working_hours"=>"", "cruise_line_ids"=>["1", "2", "15", "16", "27", "28", ""]}, "commit"=>"Update"}

保存已编辑的代理商数据和专业化(与CruiseLine的关系)

的部分
attributes = params.require(:agency).permit(
  :name, :website, :description, :booking_email, :booking_phone, 
  :optional_booking_phone, :working_hours, :cruise_line_ids
)
agency.specializations.build(attributes[:cruise_line_ids])
agency.update_attributes(attributes)

代理商数据保存没有任何问题,但在specializations表格中保存了损坏的条目:agency_id,代码ID正确,但cruise_line_id等于空字符串!!!每次保存表单时,都会向现有表单添加一个损坏的关系。

问题:

1)如何在我的情况下保存关系,导致当前代码根本不起作用?

2)如何更新这些关系(如果取消选中复选框并保存表单,还应删除未选择的关系)?

3)为什么params cruise_line_ids数组的最后一个元素是空字符串?为什么它是由collection_ckeckbox_helper生成的?

请帮忙。我在这4个小时内挣扎:(

1 个答案:

答案 0 :(得分:0)

问题出现在两个地方(关系表中的错误构建和冗余索引):

我替换了这段代码

agency.specializations.build(attributes[:cruise_line_ids])

以下内容:

attributes[:cruise_line_ids].each do |cruise_line_id|
  if cruise_line_id.to_i > 0     # to skip last empty string element?!
    agency.specializations.build(cruise_line_id: cruise_line_id)
  end
end

并在下面的代码(:cruise_line_ids => [] - 此部分)中做了一些小修改:

attributes = params.require(:agency).permit(
  :name, :website, :description, :booking_email, :booking_phone, 
  :optional_booking_phone, :working_hours, :cruise_line_ids => []
)

之后它开始导致一些PG::uniqueviolation错误。事实证明,复合唯一索引存在问题。在检查了SQL日志之后,我发现我的关系被保存了两次(当构建时和第二次更新属性时),所以我把更新属性的代码放在块之前,建立关系,一切都变得很好和完美:)

相关问题