【发布时间】:2017-11-03 16:45:33
【问题描述】:
我有以下模型及其相应的架构定义:
class Cube < ApplicationRecord
has_many :faces, inverse_of: :cube, dependent: :destroy
accepts_nested_attributes_for :faces
end
create_table "cubes", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
##
# NOTE: Even though this model's related database table has an +id+ column, it
# is not a regular auto-generated, auto-incremented ID, but rather an +id+
# column that refers to an uuid that must be manually entered for each
# Face that is created.
##
class Face < ApplicationRecord
belongs_to :cube, inverse_of: :faces, optional: true
validates :id, presence: true, uniqueness: true
end
# Note that id defaults to nil.
create_table "faces", id: :uuid, default: nil, force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.uuid "cube_id"
t.index ["cube_id"], name: "index_faces_on_cube_id"
end
从上面的 cmets 可以看出,id 不是为 Face 模型自动生成的,而是在创建它们时预计会输入(因为我们正在建模现实世界中已经有的东西)唯一标识符,我们希望使用它而不是添加另一个 ID)。
问题出现在我尝试执行以下操作时:
cube = Cube.new
cube.faces_attributes = [
{
id: "2bfc830b-fd42-43b9-a68e-b1d98e4c99e8"
}
]
# Throws the following error
# ActiveRecord::RecordNotFound: Couldn't find Face with ID=2bfc830b-fd42-43b9-a68e-b1d98e4c99e8 for Cube with ID=
对我来说,这意味着由于我们传递了一个id,Rails 期望这是对关联的Face 的更新,而不是传递一个新的Face 以创建并与cube 关联。
有没有办法让我通过accepts_nested_attributes_for 禁用此默认行为,还是我必须为我的特定用例编写自定义代码?
【问题讨论】:
-
我想如果你想在控制器动作中创建一个关联的对象,你必须用
new关键字创建它。喜欢 -face = Face.new和cube.face = face,或者类似的东西 -
@PlanB 是的,看起来它可以工作。我只是“出于好奇”询问嵌套属性的“约定优于配置”是否可以针对这种特定情况弯曲。感谢贡献
-
我认为你最好留在
Convention over configuration。并保留原始记录ID,我认为这不是问题。同一对象可以有两个 id,因为原始 id 从 0(或 1)开始,所以它不是heavy。最重要的是 - 专注于严重的问题(虽然这不是):) -
我的意思是,这看起来不是一个严重的问题,因为您不会丢失任何数据
标签: ruby-on-rails postgresql ruby-on-rails-5 accepts-nested-attributes