Ruby-on-rails 在迁移上添加行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/415287/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:53:17  来源:igfitidea点击:

Add Rows on Migrations

ruby-on-railsdatabasemigration

提问by Pablo Fernandez

I'd like to know which is the preferred way to add records to a database table in a Rails Migration. I've read on Ola Bini's book (Jruby on Rails) that he does something like this:

我想知道在 Rails 迁移中将记录添加到数据库表的首选方法是什么。我读过 Ola Bini 的书(Jruby on Rails),他做了这样的事情:

class CreateProductCategories < ActiveRecord::Migration

  #defines the AR class
  class ProductType < ActiveRecord::Base; end

  def self.up

    #CREATE THE TABLES...

    load_data
  end
  def self.load_data
    #Use AR object to create default data
    ProductType.create(:name => "type")
  end
end

This is nice and clean but for some reason, doesn't work on the lasts versions of rails...

这很好,很干净,但由于某种原因,在最新版本的 rails 上不起作用......

The question is, how do you populate the database with default data (like users or something)?

问题是,您如何使用默认数据(如用户或其他数据)填充数据库?

Thanks!

谢谢!

采纳答案by Keltia

You could use fixtures for that. It means having a yaml file somewhere with the data you want to insert.

你可以使用固定装置。这意味着在某处有一个 yaml 文件,其中包含您要插入的数据。

Here is a changeset I committed for this in one of my app:

这是我在我的一个应用程序中为此提交的变更集:

db/migrate/004_load_profiles.rb

db/migrate/004_load_profiles.rb

require 'active_record/fixtures'

class LoadProfiles < ActiveRecord::Migration
  def self.up
    down()

    directory = File.join(File.dirname(__FILE__), "init_data")
    Fixtures.create_fixtures(directory, "profiles")
  end

  def self.down
    Profile.delete_all
  end
end

db/migrate/init_data/profiles.yaml

db/migrate/init_data/profiles.yaml

admin:
 name: Admin
  value: 1
normal:
 name: Normal user
  value: 2

回答by Andrew Hodgkinson

The Rails API documentation for migrations shows a simpler way to achieve this.

用于迁移的 Rails API 文档展示了一种更简单的方法来实现这一点。

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

class CreateProductCategories < ActiveRecord::Migration
  def self.up
    create_table "product_categories" do |t|
      t.string name
      # etc.
    end

    # Now populate the category list with default data

    ProductCategory.create :name => 'Books', ...
    ProductCategory.create :name => 'Games', ... # Etc.

    # The "down" method takes care of the data because it
    # drops the whole table.

  end

  def self.down
    drop_table "product_categories"
  end
end

Tested on Rails 2.3.0, but this should work for many earlier versions too.

在 Rails 2.3.0 上测试过,但这也适用于许多早期版本。

回答by Marcio Mangar

You could also define in your seeds.rb file, for instance:

你也可以在你的 seed.rb 文件中定义,例如:

Grid.create :ref_code => 'one' , :name => 'Grade única'

and after run:

运行后:

rake db:seed

回答by user52227

your migrations have access to all your models, so you shouldn't be creating a class inside the migration.

您的迁移可以访问所有模型,因此您不应在迁移中创建类。

I am using the latest rails, and I can confirm that the example you posted definitely OUGHT to work.

我正在使用最新的 rails,我可以确认您发布的示例绝对可以正常工作。

However, migrations are a special beast. As long as you are clear, I don't see anything wrong with an ActiveRecord::Base.connection.execute("INSERT INTO product_types (name) VALUES ('type1'), ('type2')").

然而,迁徙是一种特殊的野兽。只要你清楚,我看不出ActiveRecord::Base.connection.execute("INSERT INTO product_types (name) VALUES ('type1'), ('type2')").

The advantage to this is, you can easily generate it by using some kind of GUI or web front-end to populate your starting data, and then doing a mysqldump -uroot database_name.product_types.

这样做的好处是,您可以通过使用某种 GUI 或 Web 前端来填充起始数据,然后执行mysqldump -uroot database_name.product_types.

Whatever makes things easiest for the kind of person who's going to be executing your migrations and maintaining the product.

对于将要执行迁移和维护产品的人来说,无论哪种方式都可以使事情变得最简单。

回答by Ben Trewern

You should really not use

你真的不应该使用

ProductType.create

in your migrations.

在您的迁移中。

I have done similar but in the long run they are not guaranteed to work.

我做了类似的但从长远来看,他们不能保证工作。

When you run the migration the model class you are using is the one at the time you run the migration, not the one at the time you created the migration. You will have to be sure you never change your model in such a way to stop you migration from running.

运行迁移时,您使用的模型类是运行迁移时的模型类,而不是创建迁移时的模型类。您必须确保永远不会以阻止迁移运行的方式更改模型。

You are much better off running SQL for example:

例如,您最好运行 SQL:

[{name: 'Type', ..}, .. ].each do |type|
  execute("INSERT INTO product_types (name) VALUES ('#{type[:name]} .. )
end