【问题标题】:Rails has_many :through does not save relations or saves corrupted oneRails has_many :through 不保存关系或保存损坏的关系
【发布时间】:2014-11-13 00:40:22
【问题描述】:

我有模型:

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"=&gt;"✓", "authenticity_token"=&gt;"some-long-token", "agency"=&gt;{"name"=&gt;"Test agency", "website"=&gt;"http://www.bla-bla.com", "description"=&gt;"", "booking_email"=&gt;"", "booking_phone"=&gt;"", "optional_booking_phone"=&gt;"", "working_hours"=&gt;"", "cruise_line_ids"=&gt;["1", "2", "15", "16", "27", "28", ""]}, "commit"=&gt;"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 个小时里苦苦挣扎:(

【问题讨论】:

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


    【解决方案1】:

    问题出在两个地方(不正确的构建和关系表中的冗余索引):

    我替换了这段代码

    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 =&gt; [] - 这部分)进行了小修改:

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

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

    【讨论】:

      猜你喜欢
      • 2016-10-17
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 2014-12-26
      • 1970-01-01
      相关资源
      最近更新 更多