Reputation: 8562
I have a Rake task that loads configuration data into the DB from a file, is there a correct ruby/rails way to call it on a migration up?
My objective is to sync my team DB configs, without have to broadcast then to run the task lalala
def self.up
change_table :fis_situacao_fiscal do |t|
t.remove :mostrar_endereco
t.rename :serie, :modelo
end
Faturamento::Cfop.destroy_all()
#perform rake here !
end
UPDATE How I do now, and works:
system('rake sistema:load_data file=faturamento/cfop')
And this is the suggestion from @Ryan Bigg, and it's exception:
Rake::Task['rake sistema:load_data file=faturamento/cfop'].invoke()
.
== AlterSituacaoFiscalModeloEndereco: migrating ====================
-- change_table(:fis_situacao_fiscal)
-> 0.0014s
rake aborted!
An error has occurred, this and all later migrations canceled:
Don't know how to build task 'rake sistema:load_data file=faturamento/cfop'
Where it went wrong?
Upvotes: 58
Views: 25466
Reputation: 107728
Yes! There is a way to do that.
Run the following command.
Rake::Task['your_task'].invoke
Do not put Rake inside parenthesis, just the name of the task. I recommend that you set an ENV
variable when running the following in the console.
FILE=somefile.text rake db:sistema:load_data
You can call it separately using the following example.
FILE=somefile.text rake some:other:task:that:calls:it
It will be available in your tasks as ENV['file']
.
Upvotes: 95
Reputation: 1693
You can execute a rake task from within a loaded Rails environment with either Rake::Task['namespace:task'].invoke
or Rake::Task['namespace:task'].execute
.
You can pass data to the task inside of the invoke
or execute
method. Example:
Rake::Task['namespace:task'].invoke(paramValue)
This param can be handled in the rake task as follows:
namespace :namespace do
desc "Example description."
task :task, [:param] => :environment do |t, args|
puts args[:param]
...
end
end
This can be executed on the console as:
bundle exec rake namespace:task[paramValue]
More info: https://medium.com/@sampatbadhe/rake-task-invoke-or-execute-419cd689c3bd
Upvotes: 7
Reputation: 71
This decision fits better, IMHO.
In your case it would be smth like this:
backup_env = ENV.slice('file') if ENV.key?('file')
ENV['file'] = 'faturamento/cfop'
Rake::Task['sistema:load_data'].invoke
ENV.delete 'file'
ENV.merge!(backup_env) if backup_env
Upvotes: 1
Reputation: 513
Note that if you call the Rake task with 'system', you need to check the process status afterwards and raise an exception if the Rake task failed. Otherwise the migration will succeed even if the Rake task fails.
You can check the process status like this:
if !($?.success?)
raise "Rake task failed"
end
Invoking the rake task is a nicer option - it will cause the migration to fail if the Rake task fails.
Upvotes: 10