Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 迁移到单表继承时Rails 4更新类型_Ruby_Ruby On Rails 4_Single Table Inheritance - Fatal编程技术网

Ruby 迁移到单表继承时Rails 4更新类型

Ruby 迁移到单表继承时Rails 4更新类型,ruby,ruby-on-rails-4,single-table-inheritance,Ruby,Ruby On Rails 4,Single Table Inheritance,Rails 4.0.4、Ruby 2.1.2 我想这样使用STI: User < ActiveRecord::Base Admin < User 然后我想将数据库中当前的用户更新为Admin # Place I'm currently stuck 然后我将所有信息记录移动到用户表中 Info.all.each { |info| User.create(name: info.name, email: info.email) } 除了将以前的用户转变为管理员之外,其他一切似乎都正常

Rails 4.0.4、Ruby 2.1.2

我想这样使用STI:

User < ActiveRecord::Base
Admin < User
然后我想将数据库中当前的用户更新为Admin

# Place I'm currently stuck
然后我将所有信息记录移动到用户表中

Info.all.each { |info| User.create(name: info.name, email: info.email) }
除了将以前的用户转变为管理员之外,其他一切似乎都正常工作。以下是我尝试过的一些事情:

# Seems to work, but doesn't actually save type value
User.each do |user|
  user.becomes!(Admin)
  user.save! # evaluates to true, doesn't have any errors
end

# Seems to work, but doesn't actually save type value
# I've also tried a combo of this one and the above one
User.each do |user|
  user.type = "Admin"
  user.save! # evaluates to true, doesn't have any errors
end

User.each do |user|
  user = user.becomes!(Admin)
  user.save! # evaluates to true, doesn't have any errors
end

# Seems to work, but doesn't actually save type value
User.each do |user|
  user.update_attributes(type: "Admin")
end
每次本地用户变量似乎具有正确的类型(“Admin”),并将其保存为true,但当我选中
Admin.count
或选中用户类型值时,它总是为nil。我知道您不应该更改它们,但这只是为了将数据迁移到STI,然后我就可以开始使用适当的类创建用户或管理员


至少我认为Rails应该引发一个错误,设置一个错误,或者以某种方式让开发人员知道它在保存调用失败。

结果表明,虽然
update\u attributes
对type不起作用(我还没有研究原因),
update\u column
确实起作用

因此,迁移简单地变成:

User.each do |user|
  user.update_columns(type: "Admin")
end
这种方法有效而其他更新无效的原因可能可以追溯到回调或未运行的验证。我没有可以阻止它的回调,但是对于
type


如果数据库用户中有更多行,则每个行都会变得非常慢,因为它会为每个用户进行SQL调用

通常,您可以在一次SQL调用中使用
User.update_all(field:value)
来执行此操作,但还有另一个避免此操作的原因:如果以后删除
User
模型,则迁移将不再运行

一次更新所有行而不引用模型的一种方法是在迁移中使用原始SQL:

def up
  execute "UPDATE users SET type = 'Admin' WHERE type IS NULL"
end

请注意,内存中的对象仍然属于上一个类。尝试重新加载对象,您应该会在这些用户上看到新类。我已经通过执行
User.where(…)
Admin.all
获得了与更新之前相同的结果。我肯定这比实例化所有这些对象要好得多
User.each do |user|
  user.update_columns(type: "Admin")
end
def up
  execute "UPDATE users SET type = 'Admin' WHERE type IS NULL"
end