ruby-on-rails - 为什么新数据没有以嵌套形式保存?
问题描述
在 ActiveAdmin 中,我有一个带有三重嵌套的实体编辑表单。现在我可以编辑数据库中存在的数据。他们得救了。
但如果我尝试添加新数据,则会收到 ROLLBACK 错误:
{:"blocks.texts.block"=>["must exist", "can't be blank"]}
我将再次澄清 - 此字段中的现有数据已成功更新。
但是当以这种嵌套形式创建一个新实体时,就会出现某种问题。我试图通过日志跟踪表单中发送的内容、验证之前的内容以及验证之后的内容。
一切都形成了:
"blocks_attributes"=>{"0"=>{"texts_attributes"=>{"0"=>{"value"=>"first value", "_destroy"=>"0", "id"=>"671518"}}, "label_ids"=>["", "54"], "_destroy"=>"0", "id"=>"18655"}, "1"=>{"texts_attributes"=>{"0"=>{"value"=>"tteesstt"}}}}
# => "1"=>{"texts_attributes"=>{"0"=>{"value"=>"tteesstt"}}}
但在验证前后,这些数据不再可用。仅texts
存在先前存在的数据。
在 ActiveAdmin 中有以下代码:
permit_params :title, :description, :published,
blocks_attributes: [
:id, :_destroy,
texts_attributes: %i[id value _destroy],
label_ids: []
],
category_ids: []
# ...
f.has_many :blocks, allow_destroy: true do |b_f|
b_f.inputs do
b_f.has_many :texts, allow_destroy: true do |b_t_f|
b_t_f.inputs do
b_t_f.input :value
end
end
b_f.input :labels, as: :check_boxes, collection: Label.options_for_select, input_html: { multiple: true }
end
end
初始 Post 模型具有以下代码:
accepts_nested_attributes_for :blocks,
allow_destroy: true
在块模型中:
accepts_nested_attributes_for :texts,
allow_destroy: true
请告诉我为什么现有的数据会更新,而新的数据会在保存时消失?
加法1
据我了解,这与 - 无关texts
,而是与block
-相关blocks.texts.block
。但是为什么text
指的是 a block
?为什么block
无法识别?它具有以下形式的名称:post[blocks_attributes][1][texts_attributes][0][value]
。
加法2
如果在 ActiveAdmin 中我首先只添加(保存到 DB)block
(第二个块),然后在我添加文本到 this 之后block
,所有两次保存到 DB 都将成功。也就是在单一场景下block
创建时缺少ID造成的问题。text
原来这是一个bug?添加(使用 JS)新的 HTML 表单代码时,还必须添加block_id
for text
. 但现在不是这样。现在只有数据库中的现有块有这个字段。
解决方案
解决方案很简单——需要使用inverse_of
。文档。
一切都将开始按预期工作。
推荐阅读
- uicollectionview - CollectionViewCell 未出现在 collectionView 中
- java - Jackson API 中的 asDouble() 和 doubleValue() 有什么区别?
- apache - 我的子域不断重定向到我的主域
- symfony - 加入 DQL SYMFONY
- python - 无法从我的不和谐机器人向用户发送私人消息?
- wordpress - Wordpress Graphql - 我可以按 acf 列过滤吗?
- ios - 将 UIButton 带到 UIScrollview 上方
- javascript - Three.js 在 Object3D 和 Sprite 之间绘制 Shape
- solr - 在 Solr 中创建自定义 FunctionQuery
- casting - 无法在 Entity Framework 6 中将 int 转换为对象。但是当我使用 Linq to SQL 时它可以工作