Вопрос

Опыт работы с Rails / ActiveRecord 2.1.1

  • Вы создаете первую версию с помощью (например) ruby script\generate scaffold название продукта:string описание:text image_url:строка
  • Это создаст (например) файл миграции с именем 20080910122415_create_products.rb
  • Вы применяете миграцию с помощью rake db:migrate
  • Теперь вы добавляете поле в таблицу product с помощью ruby script\generate migration add_price_to_product цена:десятичная
  • Это создаст файл переноса с именем 20080910125745_add_price_to_product.rb
  • Если вы попытаетесь запустить rake db: migrate, это фактически отменит первую миграцию, а не применит следующую!Таким образом, ваша таблица продуктов будет уничтожена!
  • Но если бы вы запустили rake в одиночку, он бы сообщил вам, что одна миграция находится на рассмотрении

Пожалуйста, обратите внимание, что при применении rake db:migrate (после уничтожения таблицы) будут применены все миграции по порядку.

Единственное обходное решение, которое я нашел, - это указать версию новой миграции, как в:

rake db:migrate version=20080910125745

Так что мне интересно:является ли это ожидаемым новым поведением?

Это было полезно?

Решение

Вы должны уметь использовать

rake db:migrate:up 

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

если ты побежишь

rake db:migrate 

дважды он повторно применит все ваши миграции.

Я сталкиваюсь с таким же поведением в Windows с помощью SQLite, это может быть ошибка, специфичная для такой среды.

Редактировать -- Я нашел почему.В задаче railstie database.rake у вас есть следующий код :

desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
task :migrate => :environment do
  ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
  ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
  Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end

Затем в моих переменных окружения у меня есть

echo %Version% #=> V3.5.0f

в Ruby

ENV["VERSION"] # => V3.5.0f
ENV["VERSION"].to_i #=>0 not nil !

таким образом, задача rake вызывает

ActiveRecord::Migrator.migrate("db/migrate/", 0)

и в ActiveRecord::Migrator у нас есть :

class Migrator#:nodoc:
  class << self
    def migrate(migrations_path, target_version = nil)
      case
        when target_version.nil?              then up(migrations_path, target_version)
        when current_version > target_version then down(migrations_path, target_version)
        else                                       up(migrations_path, target_version)
      end
    end

ДА, rake db:migrate VERSION=0 это длинная версия для rake db:migrate:down

Редактировать - Я бы пошел обновить ошибку lighthouse, но прокси-сервер super company запрещает мне подключаться туда

Тем временем вы можете попробовать сбросить версию перед вызовом migrate ...

Другие советы

Я со всем уважением не согласен, Том!это является жук !!V3.5.0f не является допустимой версией для рейковых миграций.Rake не должен использовать его для переноса:down только потому, что ruby решил учесть, что "V3.5.0f".to_i равно 0 ...

Rake должен громко жаловаться, что версия недействительна, чтобы пользователи знали, в чем дело (между нами говоря, проверить, что версия является временной меткой в формате ГГГГ, преобразованной в целое число, немного проще простого)

[Проклятый IE6, который не позволяет мне комментировать!и нет, я не могу сменить браузер, спасибо корпорации]

Это не ожидаемое поведение.Я собирался предложить сообщить об этом как об ошибке в lighthouse, но я вижу, что вы уже сделано это!Если вы предоставите дополнительную информацию (включая версию OS / database / ruby), я взгляну на нее.

Джин,

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

Что происходит, так это то, что rake захватит любое значение, которое вы передадите в командную строку, и сохранит их как переменные окружения.Задачи rake, которые в конечном итоге будут вызваны, просто извлекут эти значения из переменной окружения.Когда db: migrate запрашивает ENV["VERSION"], он фактически запрашивает параметр version, который вы установили, вызывая rake.Когда вы вызываете rake db:migrate, вы не передаете ни одной версии.

Но у нас есть переменная окружения с именем VERSION, которая была установлена для других целей какой-то другой программой (я пока не знаю, какой именно).И ребята, стоящие за rake (или за database.rake), не предполагали, что это произойдет.Это ошибка дизайна.По крайней мере, они могли бы использовать более конкретные имена переменных, такие как "RAKE_VERSION" или "RAKE_PARAM_VERSION" вместо просто "ВЕРСИИ".

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

И еще раз спасибо, Джин, за твою помощь.Я опубликовал эту ошибку на lighthouse примерно 5 дней назад и до сих пор не получил ответа!

Ролло

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top