Добавить строки по переходам

Я хотел бы знать, какой предпочтительный способ добавить записи в таблицу базы данных в 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