2011-01-13 1 views
3

Скажем, я начинаю с этой моделью:Как вы справляетесь с нарушением изменений в миграции Rails?

class Location < ActiveRecord::Base 
    attr_accessible :company_name, :location_name 
end 

Теперь я хочу, чтобы реорганизовать одно из значений в соответствующей модели.

class CreateCompanies < ActiveRecord::Migration 
    def self.up 
    create_table :companies do |t| 
     t.string :name, :null => false 
     t.timestamps 
    end 

    add_column :locations, :company_id, :integer, :null => false 
    end 

    def self.down 
    drop_table :companies 
    remove_column :locations, :company_id 
    end 
end 

class Location < ActiveRecord::Base 
    attr_accessible :location_name 
    belongs_to :company 
end 

class Company < ActiveRecord::Base 
    has_many :locations 
end 

Все это прекрасно работает во время разработки, так как я делаю все шаг за шагом; но если я попробую развернуть это в моей промежуточной среде, у меня возникнут проблемы.

Проблема заключается в том, что, поскольку мой код уже изменился, чтобы отразить миграцию, он вызывает сбой среды при попытке выполнить миграцию.

Неужели кто-то еще справился с этой проблемой? Я смирился с тем, чтобы разделить мое развертывание на несколько этапов?

ОБНОВЛЕНИЕ Похоже, я ошибаюсь; при миграции среды коллектива мы столкнулись с проблемами, но обновление было обновлено без проблем. Моя вина. Я буду отмечать ответ @ noodl как ответ, чтобы похоронить это, его сообщение - хороший совет.

+0

Какая ошибка возникает при попытке выполнить миграцию? –

ответ

9

Я думаю, что решение здесь заключается в том, чтобы не писать миграции, которые имеют любые внешние зависимости. Для выполнения ваших миграций не должно зависеть прошлое или текущее состояние вашей модели.

Это не означает, что вы не можете использовать объекты модели, просто чтобы вы не использовали версии, обнаруженные в любой версии вашего кода, которая будет установлена ​​при выполнении определенной миграции.

Вместо этого рассмотрите возможность переопределения объектов модели в файле миграции. В большинстве случаев я обнаружил, что пустой класс модели, расширяющийся ActiveRecord::Base или очень урезанная версия класса модели I, использовала в то время, когда я писал, миграция позволяет мне писать надежную, будущую доказательство, миграцию без необходимости конвертировать ruby логики в SQL.

#20110111193815_stop_writing_fragile_migrations.rb 
class StopWritingFragileMigrations < ActiveRecord::Migration 
    class ModelInNeedOfMigrating < ActiveRecord::Base 
    def matches_business_rule? 
     #logic copied from model when I created the migration 
    end 
    end 
    def self.up 
    add_column :model_in_need_of_migrating, :fancy_flag, :boolean, :default => false 

    #do some transform which would be difficult for me to do in SQL 
    ModelInNeedOfMigrating.all.each do |model| 
     model.update_attributes! :fancy_flag => true if model.created_at.cwday == 1 && model.matches_business_rule? 
     #... 
    end 
    end 

    def self.down 
    #undo that transformation as necessary 
    #... 
    end 
end 
+0

Я забыл об этом. Очень ценная техника, спасибо за публикацию. –

0

Какая ошибка возникает при запуске миграции? Вы должны быть в порядке, пока ваши файлы рейка и миграции не используют ваши модели (и они не должны).

Вы также захотите переключить порядок строк drop_table и remove_column в self.down вашей миграции.