我正在尝试创建一个表单,允许用户添加/编辑/删除与活动相关的位置。我目前找到的所有示例都是针对HABTM表单(不允许编辑存在于has_many through配置中的其他属性)或仅列出现有的关系。
下面是一个显示我想要实现的内容的图片。
列表将显示每个可用的位置。通过campaign_locations模型具有关系的位置将被选中,并且其campaign_location特定属性可编辑。未选中的位置应该可以被选中,输入campaign_location特定数据,并在提交时创建一个新的关系。
以下是我目前实现的代码。我尝试使用collection_check_boxes,这非常接近我所需要的,但它不允许我编辑campaign_location属性。
我已成功地编辑/删除现有的campaign_locations,但我无法弄清楚如何将其合并以显示所有可用的位置(如附图)。
下面是一个显示我想要实现的内容的图片。
列表将显示每个可用的位置。通过campaign_locations模型具有关系的位置将被选中,并且其campaign_location特定属性可编辑。未选中的位置应该可以被选中,输入campaign_location特定数据,并在提交时创建一个新的关系。
以下是我目前实现的代码。我尝试使用collection_check_boxes,这非常接近我所需要的,但它不允许我编辑campaign_location属性。
我已成功地编辑/删除现有的campaign_locations,但我无法弄清楚如何将其合并以显示所有可用的位置(如附图)。
模型
campaign.rb
class Campaign < ActiveRecord::Base
has_many :campaign_locations
has_many :campaign_products
has_many :products, through: :campaign_products
has_many :locations, through: :campaign_locations
accepts_nested_attributes_for :campaign_locations, allow_destroy: true
end
campaign_location.rb
class CampaignLocation < ActiveRecord::Base
belongs_to :campaign
belongs_to :location
end
location.rb
class Location < ActiveRecord::Base
has_many :campaign_locations
has_many :campaigns, through: :campaign_locations
end
View
campaign/_form.html.haml
= form_for @campaign do |campaign_form|
# this properly shows existing campaign_locations, and properly allows me
# to edit the campaign_location attributes as well as destroy the relationship
= campaign_form.fields_for :campaign_locations do |cl_f|
= cl_f.check_box :_destroy, {:checked => cl_f.object.persisted?}, false, true
= cl_f.label cl_f.object.location.title
= cl_f.datetime_field :pickup_time_start
= cl_f.datetime_field :pickup_time_end
= cl_f.text_field :pickup_timezone
# this properly lists all available locations as well as checks the ones
# which have a current relationship to the campaign via campaign_locations
= campaign_form.collection_check_boxes :location_ids, Location.all, :id, :title
表单HTML的部分内容
<input name="campaign[campaign_locations_attributes][0][_destroy]" type="hidden" value="true" /><input id="campaign_campaign_locations_attributes_0__destroy" name="campaign[campaign_locations_attributes][0][_destroy]" type="checkbox" value="false" />
<label for="campaign_campaign_locations_attributes_0_LOCATION 1">Location 1</label>
<label for="campaign_campaign_locations_attributes_0_pickup_time_start">Pickup time start</label>
<input id="campaign_campaign_locations_attributes_0_pickup_time_start" name="campaign[campaign_locations_attributes][0][pickup_time_start]" type="datetime" />
<label for="campaign_campaign_locations_attributes_0_pickup_time_end">Pickup time end</label>
<input id="campaign_campaign_locations_attributes_0_pickup_time_end" name="campaign[campaign_locations_attributes][0][pickup_time_end]" type="datetime" />
<input id="campaign_campaign_locations_attributes_0_location_id" name="campaign[campaign_locations_attributes][0][location_id]" type="hidden" value="1" />
<input id="campaign_campaign_locations_attributes_0_pickup_timezone" name="campaign[campaign_locations_attributes][0][pickup_timezone]" type="hidden" value="EST" />
<input name="campaign[campaign_locations_attributes][1][_destroy]" type="hidden" value="true" /><input id="campaign_campaign_locations_attributes_1__destroy" name="campaign[campaign_locations_attributes][1][_destroy]" type="checkbox" value="false" />
<label for="campaign_campaign_locations_attributes_1_LOCATION 2">Location 2</label>
<label for="campaign_campaign_locations_attributes_1_pickup_time_start">Pickup time start</label>
<input id="campaign_campaign_locations_attributes_1_pickup_time_start" name="campaign[campaign_locations_attributes][1][pickup_time_start]" type="datetime" />
<label for="campaign_campaign_locations_attributes_1_pickup_time_end">Pickup time end</label>
<input id="campaign_campaign_locations_attributes_1_pickup_time_end" name="campaign[campaign_locations_attributes][1][pickup_time_end]" type="datetime" />
<input id="campaign_campaign_locations_attributes_1_location_id" name="campaign[campaign_locations_attributes][1][location_id]" type="hidden" value="2" />
<input id="campaign_campaign_locations_attributes_1_pickup_timezone" name="campaign[campaign_locations_attributes][1][pickup_timezone]" type="hidden" value="EST" />
<input name="campaign[campaign_locations_attributes][2][_destroy]" type="hidden" value="true" /><input id="campaign_campaign_locations_attributes_2__destroy" name="campaign[campaign_locations_attributes][2][_destroy]" type="checkbox" value="false" />
<label for="campaign_campaign_locations_attributes_2_LOCATION 3">Location 3</label>
<label for="campaign_campaign_locations_attributes_2_pickup_time_start">Pickup time start</label>
<input id="campaign_campaign_locations_attributes_2_pickup_time_start" name="campaign[campaign_locations_attributes][2][pickup_time_start]" type="datetime" />
<label for="campaign_campaign_locations_attributes_2_pickup_time_end">Pickup time end</label>
<input id="campaign_campaign_locations_attributes_2_pickup_time_end" name="campaign[campaign_locations_attributes][2][pickup_time_end]" type="datetime" />
<input id="campaign_campaign_locations_attributes_2_location_id" name="campaign[campaign_locations_attributes][2][location_id]" type="hidden" value="3" />
<input id="campaign_campaign_locations_attributes_2_pickup_timezone" name="campaign[campaign_locations_attributes][2][pickup_timezone]" type="hidden" value="EST" />
params{}
哈希中可能会变得棘手。 - Beartech