【问题标题】:How do I add some inserts in rails migration?如何在 Rails 迁移中添加一些插入?
【发布时间】:2011-02-09 16:31:06
【问题描述】:

创建表后(通过迁移),我想直接插入一些条目。我必须如何为此编写迁移?

谢谢

【问题讨论】:

    标签: ruby-on-rails migration


    【解决方案1】:

    不要。如果您正在寻找种子数据,您应该使用db/seeds.rbrake db:seedMore info in this Railscast.

    旁注:始终确保db/seeds.rb 中的代码是幂等的。即重新运行种子应该始终是安全的。

    但是,如果您必须在迁移中插入或修改数据(有合法的用例),最好改用 SQL 语句。不保证您的模型类在您的应用程序的未来版本中仍然以相同的形式存在,并且如果您直接引用模型类,将来从头开始运行迁移可能会产生错误。

    execute "insert into system_settings (name, label, value) values ('notice', 'Use notice?', 1)"
    

    【讨论】:

    • 你说的太对了,简直太荒谬了。我只是完全搞砸了,认为编写为您的表提供种子的迁移很好。糟糕的。糟糕的。糟糕的。如果您不相信这个答案,请相信我,当我说“随着您更新代码时,您的模型会随着时间的推移而改变”。当这种情况发生时,您的播种迁移会失败并且您会丢失数据......(幸运的是我备份了这些内容)。现在我只需要弄清楚如何在事后自动将我的数据放回原处。
    • 使用创建数据表的迁移定位数据有很多好处。也许桌子在空的时候是没有意义的。也许您想将 rails 的 db 版本控制扩展到数据。也许您认为对所有种子/配置数据仅使用一个文件是 loco(它是!)。如果您唯一的原因是通过模型执行此操作是不好的,那么您不需要教条地说“从不”在迁移中添加数据。我之所以这么说,只是因为这是一个高容量的问题,知道如何做好是发帖人所要求的。
    • 我理解这背后的原因,但在我看来,添加/更新数据可能有正当理由。例如,我有一个迁移,它创建了一个新模型,将其与预先存在的模型相关联。我想为现有模型的每个实例插入新模型的新实例。创建表并在同一位置插入该表的初始数据是否有意义?我没有播种整个数据库,只是这张表。
    • @AliArslan 您显然不了解迁移的基本概念。如果您正在运行迁移,那么架构当然会在迁移运行时与预期的架构相匹配;否则,不需要运行迁移。
    • -1 由于缺乏详细的解释,例如,为什么通过迁移文件添加数据不是一个好主意。您链接到的 Railscast 视频也没有这个。它只涉及这一行的主题:“我并不是这种方法的真正粉丝。我更喜欢让迁移只专注于改变数据库模式。”听起来很主观。另一个链接似乎死了。您还提到最好改用 SQL 语句。再说一遍,为什么?一旦您添加了更好的解释,我将删除反对票。例子例子例子。
    【解决方案2】:

    更新: 这是正确答案:https://stackoverflow.com/a/2667747/7852


    这是来自ruby on rails api的示例:

     class AddSystemSettings < ActiveRecord::Migration
        # create the table
        def self.up
          create_table :system_settings do |t|
            t.string  :name
            t.string  :label
            t.text  :value
            t.string  :type
            t.integer  :position
          end
    
          # populate the table
          SystemSetting.create :name => "notice", :label => "Use notice?", :value => 1
        end
    
        def self.down
          drop_table :system_settings
        end
      end
    

    【讨论】:

    • 使用模型是不好的做法,因为模型会随着时间而变化,根据下面的响应 - 使用 SQL
    • 正如其他人所提到的,这不是正确的方法。看到这个答案:stackoverflow.com/a/2667747/7852
    【解决方案3】:

    编辑:请注意 - 上面的海报是正确的,您不应该在迁移中填充数据库。不要使用它来添加新数据,仅用于修改数据作为更改架构的一部分。

    在很多情况下,使用原始 SQL 会更好,但如果您需要在迁移过程中插入数据(例如,在将一个表拆分为多个表时进行数据转换),并且您需要一些默认的 AR 内容像方便的独立于 DB 的转义一样,您可以定义模型类的本地版本:

    class MyMigrationSucksALittle < ActiveRecord::Migration
      class MyModel < ActiveRecord::Base
        # empty guard class, guaranteed to have basic AR behavior
      end
    
      ### My Migration Stuff Here
      ### ...
    
    end
    

    请注意,这最适用于简单的情况;由于新类位于不同的命名空间 (MyMigrationSucksALittle::MyModel),因此在保护模型中声明的多态关联将无法正常工作。

    可用选项的更详细概述位于此处:http://railsguides.net/2014/01/30/change-data-in-migrations-like-a-boss/

    【讨论】:

      【解决方案4】:

      创建一个新的迁移文件,例如 047_add_rows_in_system_settings.rb

       class AddRowsInAddSystemSettings < ActiveRecord::Migration
              def self.up
                SystemSetting.create{:name => "name1", :label => "Use notice?", :value => 1}
                SystemSetting.create{:name => "name2", :label => "Use notice?", :value => 2}
               end
      
              def self.down
                SystemSetting.delete_all
              end
            end
      

      创建表时

      046_system_settings.rb

      class AddSystemSettings < ActiveRecord::Migration
          def self.up
            create_table :system_settings do |t|
              t.string  :name
              t.string  :label
              t.text  :value
              t.string  :type
              t.integer  :position
            end
      
            SystemSetting.create :name => "notice", :label => "Use notice?", :value => 1
          end
      
          def self.down
            drop_table :system_settings
          end
        end
      

      参考:-http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

      【讨论】:

      • 我喜欢这种方法,但想知道这是否真的是最佳实践?上面的用户建议不是。
      • 我不会投反对票,但正如您所说,@Tronathan,这是不好的做法。阅读我上面的评论,不要犯同样的错误。
      猜你喜欢
      • 1970-01-01
      • 2016-05-20
      • 2011-06-07
      • 2012-07-27
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2023-03-14
      • 2017-05-09
      相关资源
      最近更新 更多