gpt4 book ai didi

ruby-on-rails - Rails has_many 通过带有附加属性的表单

转载 作者:数据小太阳 更新时间:2023-10-29 07:18:23 25 4
gpt4 key购买 nike

我正在尝试创建一个允许用户添加/编辑/删除事件地点的表单。我目前找到的所有示例都是针对 HABTM 表单(不允许编辑 has_many through 配置中存在的附加属性)或仅列出现有的关系。

下面是一张图片,显示了我正在努力完成的事情。

List of locations to add to a campaign

该列表将显示每个可用位置。将检查通过 campaign_locations 模型建立关系的位置,并使它们的 campaign_location 特定属性可编辑。未选中的位置应该能够被选中,输入 campaign_location 特定数据,并在提交时创建新关系。

下面是我目前已经实现的代码。我尝试使用 collection_check_boxes,它非常接近我的需要,只是它不允许我编辑 campaign_location 属性。

我已经能够成功编辑/删除现有的 campaign_locations,但我不知道如何合并它以显示所有可用位置(如附图)。


模型

事件.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

位置.rb

class Location < ActiveRecord::Base
has_many :campaign_locations
has_many :campaigns, through: :campaign_locations
end

查看

事件/_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" />

最佳答案

您遇到的问题是空白位置尚未实例化,因此您的 View 没有任何可构建表单元素的内容。要解决此问题,您需要在 Controller 的 newedit 操作中构建空白位置。

class CampaignController < ApplicationController
def new
empty_locations = Location.where.not(id: @campaign.locations.pluck(:id))
empty_locations.each { |l| @campaign.campaign_locations.build(location: l) }
end

def edit
# do same thing as new
end
end

然后,在您的editupdate 操作中,当用户提交表单。

class CampaignController < ApplicationController
def create
params[:campaign][:campaign_locations].reject! do |cl|
cl[:pickup_time_start].blank? && cl[:pickup_time_end].blank? && cl[:pickup_timezone].blank?
end
end

def update
# do same thing as create
end
end

此外,我认为您需要一个用于 location_id 的隐藏字段。

关于ruby-on-rails - Rails has_many 通过带有附加属性的表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28704845/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com