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:
def running_tasks
@running_tasks ||= Rake.application.top_level_tasks
end
def is_running_migration?
running_tasks.include?("db:migrate")
end
And then the following in my problematic initialiser:
unless defined?(is_running_migration?) && is_running_migration?
... do whatever
end
Its perhaps not the better solution, but you can check if the table exist :
if ActiveRecord::Base.connection.tables.include?('your_table_name')
# your code goes here
end
But its generally not enough, because there could be pending migrations.
Now, you could also check if you're in a rake task :
if ActiveRecord::Base.connection.tables.include?('your_table_name') and !defined?(::Rake)
# your code goes here
end
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?
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With