我是初级Rails开发人员,在工作中我们面临以下问题:
只需为一条记录更新列的值。 我们所做的是创建这样的迁移:
class DisableAccessForUser < ActiveRecord::Migration
def change
User.where(name: "User").first.update_column(:access, false)
end
end
迁移仅适用于架构更改吗?
您建议使用其他哪些解决方案?
PS:我只能用代码更改它。无法访问控制台。
答案 0 :(得分:16)
简短版本是,因为迁移仅用于架构更改,所以您不希望使用它们来更改数据库中的实际数据。
主要问题是,如果使用rake db:schema:load
或rake db:reset
加载数据库结构,则其他开发人员可能会忽略您的数据操作迁移。两者都只使用schema.rb
文件加载最新版本的结构,并且不接触迁移。
seed.rb
文件非常适合加载初始系统数据。
希望漫无边际。
<强>更新强>
在一些“官方”来源中找到了一些文档:
seed.rd
文件中。答案 1 :(得分:2)
迁移适用于架构更改。但是当你从事许多合作项目时,比如每天从很多开发人员那里提取代码。
您可能会错过一些迁移(值更新迁移。架构更改没有问题)因为迁移取决于时间戳。
所以我们要做的是在单个命名空间中创建一个 rake任务来更新一些表值(小心它不会覆盖)
每当我们从Git更新代码时,调用NameSpace中的所有rake任务。
答案 2 :(得分:1)
迁移只是一种结构化方式,可以对模式和数据进行数据库更改。 在我看来,有些情况下使用迁移进行数据更改是合法的。
例如:
话虽如此,我不会使用迁移来更改单个用户属性。如果这是偶尔发生的事情,你应该制作一个仪表板,以便将来编辑这些数据。否则,佣金任务可能是一个不错的选择。
答案 3 :(得分:1)
使用迁移中的类进行数据更改是危险的,因为它不是未来的证据。对类的更改很容易在将来中断迁移。
例如,假设您要向用户(sample_group)添加一个新列,并在对象加载(例如after_initialize)上执行的Rails生命周期回调中访问该列。这会打破这种迁移。如果你没有在保存时跳过回调和验证(通过使用update_column),那么还有更多的方法可以打破这种迁移。
当我想在迁移中进行数据更改时,我通常会回退到SQL。可以使用execute()方法在迁移中执行任何SQL语句。要使用的确切SQL取决于正在使用的数据库,但您应该能够提出适当的数据库查询。例如在MySQL中我认为以下内容应该有效:
execute("UPDATE users SET access = 0 WHERE id IN (select id from users order by id limit 1);")
这是未来的证据。
答案 4 :(得分:0)
如果我没记错的话,更改特定记录可能有效,但我不确定。
在任何情况下,这都不是一个好习惯,只有用户才能进行架构更改。 要更新一条记录,我会使用控制台。只需在终端输入“rails console”并输入代码即可更改属性。
答案 5 :(得分:0)
使用迁移迁移数据库中的数据是没有错的,如果你做得对的话,在正确的情况下。
迁移过程中应该避免两件相关的事情(正如许多人所提到的),这两件事都不能阻止迁移数据:
在迁移中使用模型是不安全的。 User
模型中的代码可能会发生变化,当发生这种情况时,没有人会更新您的迁移,因此,如果某个同事休假3个月,请回来,并尝试运行所发生的所有迁移虽然她已经离开了,但是有人在同一时间重新命名了User
模型,你的移民将被打破,并阻止她赶上来。这只是意味着你必须使用SQL,或者(如果你决定让你的迁移实现不可知)直接在你的迁移文件中包含一个ActiveRecord模型的独立副本(嵌套在迁移类下)。
对种子数据使用迁移也没有意义,特别是当有人首次设置应用程序时,用于填充新数据库的数据,因此应用程序将运行(或将拥有应用程序的全新实例中预期的数据)。您无法使用迁移,因为您在首次设置数据库时未运行迁移,而是运行db:schema:load
。因此,维护种子数据的特殊文件:seeds.rb
。这只是意味着如果你确实需要在迁移中添加数据(为了让生产和每个人的dev数据加速),它就有资格作为种子数据(运行应用程序所必需的) ,您还需要将其添加到seeds.rb
!
但是,这些都不意味着您不应该使用迁移来迁移现有数据库中的数据。这就是它们的用途。你应该使用它们!
答案 6 :(得分:0)
这个问题很老了,我认为 Rails 方法随着时间的推移而改变。基于 https://edgeguides.rubyonrails.org/active_record_migrations.html#migrations-and-seed-data,可以在此处为新列提供数据。更准确地说,您的迁移代码还应包含“向下”块:
class DisableAccessForUser < ActiveRecord::Migration
def up
User.where(name: "User").first.update_column(:access, false)
end
def down
User.where(name: "User").first.update_column(:access, true)
end
end
如果您使用 seeds.rb 来预填充数据,也不要忘记在其中包含新的列值:
User.find_or_create_by(id: 0, name: 'User', access: false)