My rails app has a website crawler that loads the authentication credentials that the crawler uses in a rails initializer in config/initializers
. The initializer loads the authentication by calling a model method in SiteLogin model.
When I run rake db:migrate
to create the SiteLogin
model table it fails because the initializer expects the database table to already exist. I can simply comment out the code in my initializer, run the migration to create the table then uncomment the initializer code and not worry about the problem.
Problem is, I'm using Capistrano to deploy and this would mean that I'd have to deploy first without the initializer code to run the migration then deploy again with the initializer code. Is there a better way of doing this or is my approach totally wrong in this case.
Here's some code sample to better explain my case:
# 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
I had a similar issue where I needed to skip a particular initializer (for delayed job, which requires a delayed_job table being present), when running a specific rake task - in this instance db:migrate.
I added the following to my Rakefile:
And then the following in my problematic initialiser:
Its perhaps not the better solution, but you can check if the table exist :
But its generally not enough, because there could be pending migrations.
Now, you could also check if you're in a rake task :
And it could be still not enough when launching tests, because there are executed in a rake task, so you could also check if the Rails environment is test (
Rails.env.test?
).