As tarefas de rake rails fornecem acesso aos modelos do ActiveRecord?


235

Estou tentando criar uma tarefa de rake personalizada, mas parece que não tenho acesso aos meus modelos. Eu pensei que isso era algo implicitamente incluído na tarefa de trilhos.

Eu tenho o seguinte código em lib / tasks / test.rake:

namespace :test do
  task :new_task do
    puts Parent.all.inspect
  end
end

E aqui está a aparência do meu modelo pai:

class Parent < ActiveRecord::Base
  has_many :children
end

É um exemplo bastante simples, mas recebo o seguinte erro:

/> rake test:new_task
(in /Users/arash/Documents/dev/soft_deletes)
rake aborted!
uninitialized constant Parent

(See full trace by running task with --trace)

Alguma ideia? obrigado

Respostas:


410

Entendi, a tarefa deve ser como:

namespace :test do
  task :new_task => :environment do
    puts Parent.all.inspect
  end
end

Observe a => :environmentdependência adicionada à tarefa


4
o que essa sintaxe significa? está atribuindo new_taskao ambiente atual? qual é o valor atual de :environment? O Google não está ajudando.
Scott Coates

12
@scoarescoare: environment aqui é a dependência; portanto, ao executar new_task, carregue o ambiente (carregue seus modelos) primeiro e depois execute new_task.
bigpotato 30/01

3
@scoarescoare você pode verificar costume de rake doc , o primeiro exemplo irá dizer-lhe
lazybios

como conseguir a mesma coisa em Sinatra?
AMBasra

O nome do modelo deve seguir com todos e não funciona sem ele, como TodoList.all.each, não TodoList.each, por que parece funcionar?
Kick Buttowski

17

pode ser necessário solicitar sua configuração (que deve especificar todos os modelos necessários, etc.)

por exemplo:

require 'config/environment'

alternativamente, você pode apenas solicitar cada um separadamente, mas pode ter problemas ambientais que a AR não está configurada etc.)


5
Isso vai funcionar, mas vai quebrar o rake em geral! Depois de adicionar essa alteração, tente rake -T sem um banco de dados disponível. rake -T deve fornecer, felizmente, uma lista de tarefas de rake sem precisar acessar o banco de dados!
IrwinInvader 15/09

1
Depois de fazer isso, você descobrirá que quaisquer outras tarefas de rake que exijam a inicialização do aplicativo (ou seja, ativos de rake: pré-compilação) falharão com "rake abortado! O aplicativo já foi inicializado".
brent

11

Quando você começar a escrever suas tarefas de rake , use um gerador para eliminá-las.

Por exemplo:

rails g task my_tasks task_one task_two task_three 

Você receberá um stub criado em lib / tasks chamado my_tasks.rake(obviamente, use seu próprio espaço para nome).

namespace :my_tasks do

  desc "TODO"
  task :task_one => :environment do 
  end  

  desc "TODO"
  task :task_two => :environment do 
  end  

  desc "TODO"
  task :task_three => :environment do 
  end  

end

Todos os seus modelos de trilhos etc. estarão disponíveis para o ambiente atual em cada bloco de tarefas, a menos que você esteja usando o ambiente de produção ; nesse caso, você precisará exigir os modelos específicos que deseja usar. Faça isso dentro do corpo da tarefa. (IIRC, isso varia entre as diferentes versões do Rails.)


2
Você não poderia simplesmente dizer que environmenté necessário como uma dependência e, em seguida, dizer a sintaxe, em vez de incentivar o OP a confiar em utilitários "mágicos" que nem sequer usam magia?
BalinKingOfMoria Reinstate CMs 04/02

3

Com a nova sintaxe do ruby ​​hash (Ruby 1.9), o ambiente será adicionado assim à tarefa rake:

namespace :test do
  task new_task: :environment do
    puts Parent.all.inspect
  end
end

2

A dependência: environment é chamada corretamente, mas o rake ainda pode não saber sobre outras gemas das quais seus modelos dependem - em um caso meu, 'protected_attributes'.

A resposta é executar:

bundle exec rake test:new_task

Isso garante que o ambiente inclua quaisquer gemas especificadas no seu Gemfile.


1

Gere tarefa usando o comando abaixo (namespace com nome da tarefa):

rails g task test new_task

Use a sintaxe abaixo para adicionar lógica:

namespace :test do
  desc 'Test new task'
  task new_task: :environment do
    puts Parent.all.inspect
  end
end

Execute a tarefa acima usando o comando abaixo:

bundle exec rake test:new_task  

ou

 rake test:new_task
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.