我有一个四级深度模型结构:Domain>主题>装置>属性
class Domain < ApplicationRecord
has_many :subjects
end
class Subject < ApplicationRecord
has_many :devices
belongs_to: :domain
end
class Device < ApplicationRecord
has_many :properties
belongs_to: :subject
end
class Property < ApplicationRecord
belongs_to :device
end
控制器代码
def update
result = @subject.update(parameters)
if result
render json: @subject
else
render_errors(@subject.errors)
end
end
@subject
作为之前的操作检索,方法是从域开始查询模型树,分别使用域{和} domain_id
和id
参数。 parameters
只是参数的哈希,例如{name: :new_name}
更新主题时,与域的关系将丢失,即domain_id
被rails设置为NUL。作为结果,主题下面的整个模型树也将与父域断开连接。
从主题模型中删除has_many: :devices
时,一切都按预期工作。我只想更新主题并保留与父域的关系。如何使用上述模型实现这一目标?
编辑1 - 添加了两种情况的日志。
使用完整的关系模型进行记录(导致错误)
Domain Load (0.5ms) SELECT "domains".* FROM "domains" WHERE "domains"."name" = ? LIMIT ? [["name", "Manatree"], ["LIMIT", 1]]
CACHE (0.0ms) SELECT "domains".* FROM "domains" WHERE "domains"."name" = ? LIMIT ? [["name", "Manatree"], ["LIMIT", 1]]
Subject Load (0.0ms) SELECT "subjects".* FROM "subjects" WHERE "subjects"."domain_id" = ? AND "subjects"."name" = ? LIMIT ? [["domain_id", 3], ["name", "s1"], ["LIMIT", 1]]
Subject Load (0.5ms) SELECT "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]]
(0.0ms) begin transaction
Domain Load (0.0ms) SELECT "domains".* FROM "domains" WHERE "domains"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
SQL (7.1ms) UPDATE "subjects" SET "domain_id" = NULL WHERE "subjects"."domain_id" = ? AND "subjects"."id" = 5 [["domain_id", 3]]
Subject Exists (0.0ms) SELECT 1 AS one FROM "subjects" WHERE "subjects"."domain_id" = ? AND "subjects"."name" = ? LIMIT ? [["domain_id", 3], ["name", "s2"], ["LIMIT", 1]]
SQL (1.0ms) UPDATE "subjects" SET "name" = ?, "updated_at" = ? WHERE "subjects"."id" = ? [["name", "s2"], ["updated_at", "2017-07-31 08:46:38.171240"], ["id", 5]]
(7.5ms) commit transaction
Subject Load (0.0ms) SELECT "subjects".* FROM "subjects"
Completed 200 OK in 30ms (Views: 0.5ms | ActiveRecord: 16.6ms)
从主题模型中删除belongs_to: :devices
时记录
Domain Load (0.0ms) SELECT "domains".* FROM "domains" WHERE "domains"."name" = ? LIMIT ? [["name", "Manatree"], ["LIMIT", 1]]
CACHE (0.0ms) SELECT "domains".* FROM "domains" WHERE "domains"."name" = ? LIMIT ? [["name", "Manatree"], ["LIMIT", 1]]
Subject Load (0.5ms) SELECT "subjects".* FROM "subjects" WHERE "subjects"."domain_id" = ? AND "subjects"."name" = ? LIMIT ? [["domain_id", 3], ["name", "s3"], ["LIMIT", 1]]
Subject Load (0.5ms) SELECT "subjects".* FROM "subjects" WHERE "subjects"."id" = ? LIMIT ? [["id", 6], ["LIMIT", 1]]
(0.0ms) begin transaction
Domain Load (0.5ms) SELECT "domains".* FROM "domains" WHERE "domains"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
SQL (6.5ms) UPDATE "subjects" SET "name" = ?, "updated_at" = ? WHERE "subjects"."id" = ? [["name", "s4"], ["updated_at", "2017-07-31 08:48:57.962218"], ["id", 6]]
(7.0ms) commit transaction
Subject Load (0.0ms) SELECT "subjects".* FROM "subjects"
Completed 200 OK in 25ms (Views: 0.4ms | ActiveRecord: 15.1ms)
编辑2 - 种子数据可能有问题......
domainA = Domain.create(name: :company)
s1 = domainA.subjects.create(name: :subject)
# domainA.save
d1 = s1.devices.create(name: :device)
# s1.save
p1 = d1.properties.create(name: :prop1, property_type: :double, value: 10.0)
p2 = d1.properties.create(name: :prop2, property_type: :string, value: :on)
p3 = d1.properties.create(name: :prop3, property_type: :string, value: :Lamp)
# d1.save
domainA.save
答案 0 :(得分:1)
从主题模型中删除has_many :: devices时,一切 按预期工作。
继续使用您的模型,您的Device
模型存在缺陷。您belongs_to :device
内有Device
。也许你应该按照协会belongs_to :subject
。这可能会导致您当前的问题。尝试更改Device
模型,如此
class Device < ApplicationRecord
has_many :properties
belongs_to: :subject
end