Предоставляют ли рельсовые задачи доступ к моделям ActiveRecord?


235

Я пытаюсь создать пользовательскую задачу, но, похоже, у меня нет доступа к моим моделям. Я думал, что это было что-то неявно включенное в задачу рельсов.

У меня есть следующий код в lib / tasks / test.rake:

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

А вот как выглядит моя родительская модель:

class Parent < ActiveRecord::Base
  has_many :children
end

Это довольно простой пример, но я получаю следующую ошибку:

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

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

Любые идеи? Спасибо

Ответы:


410

Разобрался, задача должна выглядеть так:

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

Обратите внимание на => :environmentзависимость, добавленную к задаче


4
что означает этот синтаксис? это присваивает new_taskтекущую среду? какова текущая стоимость :environment? гугл не помогает.
Скотт Коутс

12
@scoarescoare: среда здесь является зависимостью, поэтому при запуске new_taskсначала загрузите среду (загрузите ваши модели), а затем запустите new_task.
bigpotato

3
@scoarescoare, вы можете проверить пользовательские документы рейка , первый пример скажет вам
lazybios

как добиться того же в Синатре?
AMBasra

Название модели должно следовать за всеми, и оно не работает без него, как TodoList.all.each, а не TodoList.each idk, почему оно работает?
Kick Buttowski

17

вам может потребоваться ваша конфигурация (в которой должны быть указаны все необходимые модели и т. д.)

например:

require 'config/environment'

в качестве альтернативы вы можете просто требовать каждого отдельно, но у вас могут быть проблемы с окружающей средой, не настроенные и т. д.)


5
Это сработает, но в целом грабли сломает! После добавления этого изменения попробуйте rake -T без доступной БД. rake -T должен с радостью предоставить список задач rake без необходимости доступа к БД!
irkenInvader

1
После этого вы обнаружите, что любые другие задачи rake, требующие инициализации приложения (т.е. rake assets: precompile), завершатся с ошибкой «rake aborted! Приложение уже инициализировано».
Брент

11

Когда вы начнете писать свои рейковые задачи, используйте генератор, чтобы заглушить их для вас.

Например:

rails g task my_tasks task_one task_two task_three 

Вы получите заглушку, созданную в lib / tasks, которая называется my_tasks.rake(очевидно, используется ваше собственное пространство имен.), Которая будет выглядеть следующим образом:

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

Все ваши модели рельсов и т. Д. Будут доступны для текущей среды из каждого блока задач, если только вы не используете производственную среду, и в этом случае вам потребуются конкретные модели, которые вы хотите использовать. Сделайте это в теле задачи. (IIRC это варьируется между различными версиями Rails.)


2
Не могли бы вы просто сказать, что environmentэто требуется как зависимость, а затем сказать синтаксис, а не поощрять OP полагаться на «магические» утилиты, которые даже не используют магию?
BalinKingOfMoria восстанавливает CM

3

С новым синтаксисом хэша ruby ​​(Ruby 1.9) среда будет добавлена ​​в задачу rake следующим образом:

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

2

Зависимость: environment достаточно корректно вызывается, но rake все еще может не знать о других драгоценных камнях, от которых зависят ваши модели - в одном из моих случаев - protected_attributes.

Ответ заключается в следующем:

bundle exec rake test:new_task

Это гарантирует, что среда включает в себя любые драгоценные камни, указанные в вашем Gemfile.


1

Создайте задачу, используя следующую команду (пространство имен с именем задачи):

rails g task test new_task

Используйте синтаксис ниже, чтобы добавить логику:

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

Запустите вышеуказанную задачу, используя следующую команду:

bundle exec rake test:new_task  

или

 rake test:new_task
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.