Как пропустить загрузку инициализаторов Rails при выполнении задачи рейка?
В моем приложении rails есть искатель веб-сайта, который загружает учетные данные для проверки подлинности, которые искатель использует в инициализаторе rails в config/initializers
. Инициализатор загружает аутентификацию, вызывая метод модели в модели SiteLogin.
Когда я запускаю rake db:migrate
для создания таблицы модели SiteLogin
, она терпит неудачу, потому что инициализатор ожидает, что таблица базы данных уже существует. Я могу просто прокомментировать код в моем инициализаторе, запустить миграцию, чтобы создать таблицу, а затем раскомментировать код инициализатора и не беспокоиться о проблеме.
Проблема в том, что я использую Capistrano для развертывания, и это означало бы, что мне придется сначала развернуть без кода инициализатора для запуска миграции, а затем снова развернуть код инициализатора. Есть ли лучший способ сделать это, или мой подход совершенно неверен в этом случае.
Вот пример кода, чтобы лучше объяснить мой случай:
# config/initializers/site_crawler_init.rb
SiteCrawler.setup do |config|
config.hostname = "www.example.com"
end
# model/site_crawler.rb
class SiteCrawler
...
class << self
attr_accessor :configuration
def setup
self.configuration ||= Configuration.new
yield(configuration)
end
end
class Configuration
attr_accessor :hostname, :login_credentials
def initialize
@login_credentials = SiteLogin.admin_user
...
end
end
end
Ответы
Ответ 1
Возможно, это не лучшее решение, но вы можете проверить, существует ли таблица:
if ActiveRecord::Base.connection.tables.include?('your_table_name')
# your code goes here
end
Но его в целом недостаточно, потому что могут быть ожидающие миграции.
Теперь вы также можете проверить, есть ли у вас задача с граблями:
if ActiveRecord::Base.connection.tables.include?('your_table_name') and !defined?(::Rake)
# your code goes here
end
И при запуске тестов его все еще не хватит, потому что они выполняются в команде rake, поэтому вы также можете проверить, является ли среда Rails тестовой (Rails.env.test?
).
Ответ 2
У меня была аналогичная проблема, когда мне нужно было пропустить определенный инициализатор (для замедленного задания, для которого требуется таблица delayed_job), при запуске определенной задачи rake - в этом случае db: migrate.
В мой Rakefile я добавил следующее:
def running_tasks
@running_tasks ||= Rake.application.top_level_tasks
end
def is_running_migration?
running_tasks.include?("db:migrate")
end
И затем в моем проблемном инициализаторе следующее:
unless defined?(is_running_migration?) && is_running_migration?
... do whatever
end