我的数据模型中有一些STI。有两种类型的Task
记录:PrimaryTask
和SecondaryTask
。所以我的ActiveRecord模型看起来像这样:
class Task < ActiveRecord::Base
end
class PrimaryTask < Task
has_many :secondary_tasks
end
class SecondaryTask < Task
belongs_to :primary_task
end
我想提供一种永久性地将SecondaryTask
“推广”到PrimaryTask
的方法(如在数据库中持久存储)。通过仔细阅读文档,看起来the #becomes!
method就像我想要的那样,但我无法将其保存到数据库中。
id = 1
secondary_task = SecondaryTask.find(id)
primary_task = secondary_task.becomes!(PrimaryTask)
primary_task.id # => 1
primary_task.class # => PrimaryTask
primary_task.type # => "PrimaryTask"
primary_task.new_record? # => false
primary_task.changes # => { "type"=>[nil,"PrimaryTask"] }
primary_task.save! # => true
primary_task.reload # => raises ActiveRecord::RecordNotFound: Couldn't find PrimaryTask with id=1 [WHERE "tasks"."type" IN ('PrimaryTask')]
# Note: secondary_task.reload works fine, because the task's type did not change in the DB
知道怎么了?我试过以下的事情,但没有用。我误解了becomes!
吗?
save!
调用是无操作,则强制记录为“脏”,因为没有任何属性标记为脏(primary_task.update_attributes(updated_at: Time.current)
- 没有帮助)secondary_task
,则销毁id
是一个问题。没有帮助。 SecondaryTask
记录已删除但未创建PrimaryTask
(尽管调用save!
返回true
)更新1
日志显示可能的问题:
UPDATE "tasks" SET "type" = $1 WHERE "tasks"."type" IN ('PrimaryTask') AND "tasks"."id" = 2 [["type", "PrimaryTask"]]
因此更新失败,因为WHERE
子句导致找不到记录。
答案 0 :(得分:0)
想出来。事实证明ActiveRecord
版本4.0.0中存在错误。 It has since been patched。此修补程序引入的关键更改是在两个实例中正确设置changes
。所以现在你可以在原始实例上调用save
(在我的例子secondary_task
中),它将改变数据库中的类型。请注意,在新实例(对我save
)上调用primary_task
将不会保存更改,因为问题中描述的行为:它将在SQL中包含WHERE
子句{ {1}}调用将导致无法找到记录,从而调用不执行任何操作。
这适用于ActiveRecord&gt; 4.1.0:
UPDATE