2010-04-19 1 views

ответ

4

Update: Это правильный ответ: 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 
+6

Использование модели - это плохая практика, так как модели меняются со временем, за ответ ниже - используйте SQL –

+2

Как уже упоминалось, это неправильный подход. См. Этот ответ: http://stackoverflow.com/a/2667747/7852 – givanse

3

создать новый миграционный файл как 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 

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

+0

Мне нравится этот подход, но мне интересно, если это действительно лучшая практика? Вышеупомянутый пользователь говорит о том, что это не так. – Tronathan

+2

Я не буду голосовать, но это плохая практика, как вы сказали, @ Тронатан. Прочитайте мой комментарий выше и не делайте ту же ошибку, что и я. – mkralla11

74

Не. Если вы ищете данные семян, вместо этого вы должны использовать db/seeds.rb и rake db:seed. More info in this Railscast.

Но если вы должны вставлять или изменять данные внутри миграции, лучше использовать SQL-запросы. В будущей версии вашего приложения не гарантируется, что ваш модельный класс будет оставаться в одной и той же форме, а запуск миграции с нуля в будущем может привести к ошибкам, если вы напрямую ссылаетесь на класс модели.

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

Точно то, что я писал. Выписанная версия Railscast находится здесь: http://asciicasts.com/episodes/179-seed-data –

+5

Вы настолько невероятно правы, что это смешно. Я просто полностью придумал много времени, думая, что хорошо писать миграции, которые засевают ваши таблицы. Грозный. Грозный. Грозный. Если вы не доверяете этому ответу, поверьте мне, когда я скажу: «Ваши модели WILL и DO меняются с течением времени, когда вы обновляете свой код». Когда это произойдет, ваши миграция посевов повреждена, и вы LOSE DATA .... (к счастью, я все в порядке). Теперь мне просто нужно выяснить, как вернуть мои данные в автоматическом режиме после этого. – mkralla11

+3

Есть преимущества для поиска ваших данных с помощью миграции, которая создает ее таблицу. Может быть, таблица пуста. Возможно, вы хотите расширить управление версиями рельсов db на данные. Возможно, вы думаете, что использование только одного файла для всех данных семян/конфигурации - loco (это!). Вам не нужно догматично говорить «НИКОГДА» добавить данные в миграцию, если ваша единственная причина в том, что делать это с помощью моделей плохо. Я только говорю это, потому что это вопрос большого объема, и знание того, как это сделать, - это то, что задал плакат. –

4

Редактировать: ОБРАТИТЕ ВНИМАНИЕ - Плакаты, приведенные выше, являются правильными, вы не должны заполнять DB внутри миграций. Не используйте это для добавления новых данных, только для изменения данных как части изменения схемы.

Для многих вещей предпочтительным будет использование raw 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/