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

gmoniey
fonte

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

gmoniey
fonte
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.)

Luke Schafer
fonte
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.)

ocodo
fonte
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
apadana
fonte
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.

Lex Lindsey
fonte
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
Ni3
fonte