Добавить строки по переходам
Я хотел бы знать, какой предпочтительный способ добавить записи в таблицу базы данных в Rails Migration. Я прочитал книгу Ола Бини (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
Это хорошо и чисто, но по какой-то причине не работает на последних версиях рельсов...
Вопрос в том, как вы заполняете базу данных данными по умолчанию (например, пользователями или чем-то)?
Спасибо!
Ответы
Ответ 1
Для этого вы можете использовать светильники. Это означает, что где-нибудь есть файл yaml с данными, которые вы хотите вставить.
Вот набор изменений, который я сделал для этого в одном из моих приложений:
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
admin:
name: Admin
value: 1
normal:
name: Normal user
value: 2
Ответ 2
Документация API Rails для миграции показывает более простой способ достижения этой цели.
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
Протестировано на Rails 2.3.0, но это должно работать и для многих ранних версий.
Ответ 3
Вы также можете определить в файле seeds.rb, например:
Grid.create :ref_code => 'one' , :name => 'Grade Única'
и после запуска:
rake db:seed
Ответ 4
ваши миграции имеют доступ ко всем вашим моделям, поэтому вы не должны создавать класс внутри миграции.
Я использую последние рельсы, и я могу подтвердить, что пример, который вы разместили, определенно OUGHT для работы.
Однако миграции являются особым зверем. Пока вы поняли, я не вижу ничего плохого в ActiveRecord::Base.connection.execute("INSERT INTO product_types (name) VALUES ('type1'), ('type2')")
.
Преимущество этого заключается в том, что вы можете легко сгенерировать его, используя какой-то графический интерфейс или веб-интерфейс для заполнения ваших исходных данных, а затем выполнив mysqldump -uroot database_name.product_types
.
Независимо от того, что облегчает работу человека, который будет выполнять ваши миграции и поддерживать продукт.
Ответ 5
Вы действительно не должны использовать
ProductType.create
в ваших миграциях.
Я сделал подобное, но в конечном итоге они не гарантированно работают.
При запуске миграции класс модели, который вы используете, является тем, который вы выполняете при миграции, а не той, которая была на момент создания миграции. Вы должны быть уверены, что никогда не изменяете свою модель таким образом, чтобы остановить переход от работы.
Вы гораздо лучше запускаете SQL, например:
[{name: 'Type', ..}, .. ].each do |type|
execute("INSERT INTO product_types (name) VALUES ('#{type[:name]} .. )
end