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
Add Rows on Migrations
提问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

