Bieten Rails-Rake-Tasks Zugriff auf ActiveRecord-Modelle?


235

Ich versuche, eine benutzerdefinierte Rechenaufgabe zu erstellen, aber anscheinend habe ich keinen Zugriff auf meine Modelle. Ich dachte, dies sei implizit in der Rails-Aufgabe enthalten.

Ich habe den folgenden Code in lib / task / test.rake:

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

Und so sieht mein Elternmodell aus:

class Parent < ActiveRecord::Base
  has_many :children
end

Es ist ein ziemlich einfaches Beispiel, aber ich erhalte den folgenden Fehler:

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

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

Irgendwelche Ideen? Vielen Dank

Antworten:


410

Wenn ich es herausgefunden habe, sollte die Aufgabe folgendermaßen aussehen:

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

Beachten Sie die => :environmentder Aufgabe hinzugefügte Abhängigkeit


4
Was bedeutet diese Syntax? es wird new_taskder aktuellen Umgebung zugewiesen? Was ist der aktuelle Wert von :environment? Google hilft nicht.
Scott Coates

12
@scoarescoare: Umgebung ist hier die Abhängigkeit. new_taskLaden Sie also beim Ausführen zuerst die Umgebung (laden Sie Ihre Modelle) und dann new_task.
Bigpotato

3
@scoarescoare Sie können benutzerdefinierte Rake doc überprüfen , das erste Beispiel wird Ihnen sagen
Lazybios

Wie kann man in Sinatra dasselbe erreichen?
AMBasra

Modellname muss mit allen folgen und es funktioniert nicht ohne es wie TodoList.all.each nicht TodoList.each idk warum scheint es zu funktionieren?
Kick Buttowski

17

Möglicherweise müssen Sie Ihre Konfiguration benötigen (die alle erforderlichen Modelle usw. angeben sollte).

z.B:

require 'config/environment'

Alternativ können Sie jedes einzeln anfordern, aber möglicherweise haben Sie Umgebungsprobleme, die AR nicht eingerichtet hat usw.)


5
Dies wird funktionieren, aber es wird im Allgemeinen Rechen brechen! Versuchen Sie nach dem Hinzufügen dieser Änderung Rake -T, ohne dass eine Datenbank verfügbar ist. Rake -T sollte gerne eine Liste von Rake-Aufgaben bereitstellen, ohne Zugriff auf die DB zu benötigen!
IrkenInvader

1
Danach werden Sie feststellen, dass alle anderen Rake-Aufgaben, die eine Initialisierung der Anwendung erfordern (z. B. Rake-Assets: Vorkompilierung), mit "Rake abgebrochen! Anwendung wurde bereits initialisiert" fehlschlagen.
Brent

11

Wenn Sie mit dem Schreiben Ihrer Rechenaufgaben beginnen , verwenden Sie einen Generator, um sie für Sie zu löschen.

Beispielsweise:

rails g task my_tasks task_one task_two task_three 

Sie erhalten einen in lib / task erstellten Stub mit dem Namen my_tasks.rake(verwenden Sie offensichtlich Ihren eigenen Namespace). Dieser sieht folgendermaßen aus:

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

Alle Ihre Schienenmodelle usw. sind für die aktuelle Umgebung in jedem Taskblock verfügbar, es sei denn, Sie verwenden die Produktionsumgebung . In diesem Fall müssen Sie die spezifischen Modelle benötigen, die Sie verwenden möchten. Tun Sie dies im Rahmen der Aufgabe. (IIRC dies variiert zwischen verschiedenen Versionen von Rails.)


2
Könnten Sie nicht einfach sagen, dass environmentdies als Abhängigkeit erforderlich ist, und dann die Syntax sagen, anstatt das OP zu ermutigen, sich auf "magische" Dienstprogramme zu verlassen, die nicht einmal Magie verwenden?
BalinKingOfMoria CMs wieder herstellen

3

Mit der neuen Ruby-Hash-Syntax (Ruby 1.9) wird die Umgebung der Rake-Aufgabe folgendermaßen hinzugefügt:

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

2

Die: Umgebungsabhängigkeit wird ganz korrekt angegeben, aber Rake weiß möglicherweise noch nichts über andere Edelsteine, von denen Ihre Modelle abhängen - in einem Fall von mir 'protected_attributes'.

Die Antwort ist zu laufen:

bundle exec rake test:new_task

Dies garantiert, dass die Umgebung alle in Ihrer Gemfile angegebenen Edelsteine ​​enthält.


1

Generieren Sie eine Aufgabe mit dem folgenden Befehl (Namespace mit Aufgabenname):

rails g task test new_task

Verwenden Sie die folgende Syntax, um Logik hinzuzufügen:

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

Führen Sie die obige Aufgabe mit dem folgenden Befehl aus:

bundle exec rake test:new_task  

oder

 rake test:new_task
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.