在控制器中运行rake任务


Answers:


63

我同意ddfreynee的观点,但是如果您知道所需的代码,可能会如下所示:

require 'rake'

Rake::Task.clear # necessary to avoid tasks being loaded several times in dev mode
Sample::Application.load_tasks # providing your application name is 'sample'

class RakeController < ApplicationController

  def run
    Rake::Task[params[:task]].reenable # in case you're going to invoke the same task second time.
    Rake::Task[params[:task]].invoke
  end

end

您可以改为在初始化程序中要求“ rake”和.load_tasks。


我在哪里可以找到我的“应用程序名称”?
pdxleif 2012年

@pxdleifconfig/application.rb假设您使用的是Rails,它的名称大约为12行。
蒂姆·弗莱彻

2
您还可以通过致电Rails.application
declan

2
这很棒!就像其他人很清楚的那样,该方法用于同步调用rake任务(在rake完成之前,页面不会呈现)。对于异步使用,从这个轨使用call_rake投:railscasts.com/episodes/127-rake-in-background
portforwardpodcast

实际上,经过更多工作之后,我在Rails 3.2.13上的应用仅需要Sample :: Application.load_tasks行。如果我在我的应用程序中包含Task.clear行,直到我调用第一个rake,它就会给我一个关于为doc:app进行自定义覆盖的错误。但这只是我的应用程序
-portforwardpodcast

59

我发现在代码中调用rake任务不是一种好的样式。我建议将要执行的任务的代码放在rake任务之外的某个地方,并让rake任务调用此代码。

这不仅具有易于在外部rake上调用(这是您想要的)的优点,而且还使测试rake任务更加容易。


6
我同意+1:这是应该以两种不同方式重构和调用的事物的完美示例。
James A. Rosen

7
railscasts.com/episodes/127-rake-in-background 似乎是一个很好的理由来运行耙..
baash05

4
一个好的“某处”应该在“耙任务之外的某处”呢?
user456584

@ user456584(如果与模型有关),将其放在模型类中。如果与其他内容有关,请创建一个包含它们的新文件。

2
在我来说,我需要运行一个第三方的lib任务,所以我不能重构它(不通过分叉的麻烦会等)
塞萨尔Izurieta

18

与其尝试在控制器中调用rake任务,不如调用包含您要执行的逻辑的服务对象。

class SomeController < ApplicationController
  def whatever
    SomeServiceObject.call
  end
end

...然后,假设您正在谈论自定义的rake任务,请将其也调用服务对象:

namespace :example do
  desc 'important task'
  task :important_task do
    SomeServiceObject.call
  end
end

如果您不熟悉服务对象,它们只是做特定工作的普通旧红宝石类。如果您尝试调用某些默认的rake任务(即db:migrate),则强烈建议不要从控制器执行此类操作。


1
这是一种非常干净的方法。谢谢。
juliangonzalez '16

17

您可以在控制器中执行此操作:

%x[rake name_task]

with:name_task是您任务的名称


2
您如何将环境传递给它?
serengeti12

4
在生产中,我永远不会掏出我的控制器。
公爵

21
@Duke,当您回答或评论时,您还可以解释您的理由而不仅仅是断言吗(生产中的控制器不应调用rake任务)?这将帮助人们理解您的推理,而不是仅仅知道您不会做的事情(但不会听到您对原因的解释)。
马特

6
@Matt脱壳意味着Rake将在另一个进程中执行。这意味着它将启动一个新的红宝石解释器。还可能发生注入,从而导致执行任意命令(这样做有一些错别字)。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.