web-dev-qa-db-fra.com

Exécuter une tâche Rake à partir de la migration?

J'ai une tâche Rake qui charge les données de configuration dans la base de données à partir d'un fichier. Existe-t-il une méthode Ruby/Rails correcte pour l'appeler lors d'une migration ultérieure?

Mon objectif est de synchroniser les configurations de ma base de données d’équipe, sans avoir à diffuser puis à exécuter la tâche 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

UPDATEComment je fais maintenant et fonctionne:

system('rake sistema:load_data file=faturamento/cfop')

Et voici la suggestion de @Ryan Bigg , et c'est une 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'

Où ça a mal tourné?

43
Fabiano Soriani

Oui, il y a un moyen de faire ça:

Rake::Task['your_task'].invoke

Mettre à jour

Ne mettez pas rake entre les crochets, mais simplement le nom de la tâche Vous devriez définir une variable ENV lorsque vous exécutez ceci:

Dans la console

FILE=somefile.text rake db:sistema:load_data

Appelant séparément

FILE=somefile.text rake some:other:task:that:calls:it

Ce sera disponible dans vos tâches en tant que ENV['file']

77
Ryan Bigg

Notez que si vous appelez la tâche Rake avec 'système', vous devez ensuite vérifier l'état du processus et générer une exception si la tâche Rake a échoué. Sinon, la migration réussira même si la tâche Rake échoue.

Vous pouvez vérifier l'état du processus comme ceci:

if !($?.success?)
  raise "Rake task failed"
end

L'appel de la tâche de ratissage est une option plus intéressante. Cela entraînera l'échec de la migration en cas d'échec de la tâche de ratissage.

9
Leslie Viljoen

Cette décision convient mieux, à mon humble avis.

Dans votre cas, cela ressemblerait à ceci:

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

Vous pouvez exécuter une tâche rake à partir d'un environnement Rails chargé avec Rake::Task['namespace:task'].invoke ou Rake::Task['namespace:task'].execute.

Vous pouvez transmettre des données à la tâche à l'intérieur de la méthode invoke ou execute. Exemple:

Rake::Task['namespace:task'].invoke(paramValue)

Ce paramètre peut être géré dans la tâche rake comme suit:

namespace :namespace do
  desc "Example description."
  task :task, [:param] => :environment do |t, args|
    puts args[:param]
    ...
  end
end

Ceci peut être exécuté sur la console en tant que:

bundle exec rake namespace:task[paramValue]

Plus d'infos: https://medium.com/@sampatbadhe/rake-task-invoke-or-execute-419cd689c3bd

0
Jacob Dalton