我最近开始在我正在进行的项目中使用 Hotwire。一直在关注 GoRails 上的这个tutorial。目前在以动态形式添加/更新记录方面存在一些问题。我有两个模型具有
belongs_to
和 has_many
关系。
ProgramPart < ApplicationRecord
has_many :rich_contents, dependent: :destroy
accepts_nested_attributes_for :rich_contents, reject_if: :all_blank, allow_destroy: true
end
class RichContent < ApplicationRecord
belongs_to :program_part
has_rich_text :content
end
在一个表单中,我有一个按钮,用户可以在其中动态添加
RichContent
字段:
我的
ProgramPart
表格的相关部分如下所示:
<div id="block_elements" class="col-span-6 space-y-6">
<% @program_part.rich_contents.each do |content| %>
<%= render(RichContent::RichContentFormComponent.new(rich_content: content)) %>
<% end %>
</div>
<div class="col-span-6">
<span>
<%= link_to "Text and media", new_company_program_program_part_rich_content_path(@company, @program, @program_part.persisted? ? @program_part.id : Time.now.to_i), data: { turbo_stream: true } %>
</span>
</div>
<div class="bg-gray-50">
<%= part_form.submit class: "#{submit_classes}" %>
</div>
我有一个
.turbo_stream.erb
文件,我在其中呈现我的 RichContent
的表单:
<%= turbo_stream.append "block_elements" do %>
<%= render(RichContent::RichContentFormComponent.new(rich_content: @rich_content)) %>
<% end %>
# @rich_content = RichContent.new in controller
我的
ViewComponent
表格看起来像这样:
<%= fields_for "program_part[rich_contents_attributes][#{@rich_content.persisted? ? @rich_content.id : Time.now.to_i }]", @rich_content do |rich_content_form| %>
<%= render(Forms::InputLabelComponent.new(label: "Text and media", form_builder: rich_content_form, model_attribute: :content)) do %>
<%= rich_content_form.rich_text_area :content %>
<% end %>
<% end %>
我遇到的问题是在编辑
ProgramParts
时,更新现有值不起作用,它会创建新实例。假设我有内容“1”,去编辑,将值更新为“2”提交表单,然后它插入内容“1”和“2”作为新记录。
提交时表单参数看起来像这样
Processing by ProgramPartsController#update as TURBO_STREAM
14:28:07 web.1 | Parameters: {"authenticity_token"=>"[FILTERED]", "program_part"=>{"title"=>"Test", "description"=>"", "rich_contents_attributes"=>. {"152"=>{"content"=>"<div>2</div>"}}}, "commit"=>"Update Program part", "company_id"=>"1", "program_id"=>"9", "id"=>"27"}
给出以下结果:
关于我遗漏了什么或者为什么它不更新现有记录而是添加新记录的任何想法?
您需要一个带有嵌套字段的
id
属性:
<%= fields_for "program_part[rich_contents_attributes][#{@rich_content.persisted? ? @rich_content.id : Time.now.to_i }]", @rich_content do |rich_content_form| %>
<%= render(Forms::InputLabelComponent.new(label: "Text and media", form_builder: rich_content_form, model_attribute: :content)) do %>
<%= rich_content_form.rich_text_area :content %>
<%= rich_content_form.hidden_field :id if rich_content_form.object.persisted? %>
<% end %>
<% end %>
不使用嵌套属性中的键,它只是将字段组合在一起,这就是为什么
Time.now.to_i
也可以使用的原因:
"rich_contents_attributes" => {"152"=>{"content"=>"<div>2</div>"}
# ^ not used