我有模特:
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个小时内挣扎:(
答案 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日志之后,我发现我的关系被保存了两次(当构建时和第二次更新属性时),所以我把更新属性的代码放在块之前,建立关系,一切都变得很好和完美:)