ActiveRecord #becomes!记录不保存

时间:2014-09-03 23:20:42

标签: ruby-on-rails ruby activerecord

我的数据模型中有一些STI。有两种类型的Task记录:PrimaryTaskSecondaryTask。所以我的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子句导致找不到记录。

1 个答案:

答案 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