更新时轨道多级关系被破坏



我有一个四级深度模型结构:域>主题>设备>属性

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_idid参数。parameters只是参数的哈希,例如{name: :new_name}

更新主题时,与域的关系丢失,即domain_id通过导轨设置为 NULL。因此,主题下方的整个模型树也将与父域断开连接。

从主题模型中删除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

从主题模型中删除has_many时::d evices,所有内容 按预期工作。

继续使用您的模型,您的Device模型是有缺陷的。你在Device里面有belongs_to :device.也许你应该按照协会belongs_to :subject。这可能会导致您当前的问题。尝试像这样更改Device模型

class Device < ApplicationRecord 
has_many :properties
belongs_to: :subject
end

最新更新