当运行rake任务时,如何跳过加载Rails初始化程序?

21
我的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
2个回答

19

也许不是最好的解决方案,但你可以检查表是否存在:

if ActiveRecord::Base.connection.tables.include?('your_table_name')
  # your code goes here
end

通常这不够,因为可能存在有待迁移的内容。

现在,您还可以检查是否在rake任务中:

if ActiveRecord::Base.connection.tables.include?('your_table_name') and !defined?(::Rake)
  # your code goes here
end

当运行测试时,可能仍然不足够,因为它们在Rake任务中执行,所以您还可以检查Rails环境是否为测试环境 (Rails.env.test?)。


15

我曾经遇到过类似的问题,需要在运行特定的rake任务(在这种情况下是db:migrate)时跳过特定的初始化程序(对于需要存在delayed_job表的延迟工作来说)。我在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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接