I'd like to run a rake task in my controller. Is there any way to do this?
-
1http://railscasts.com/episodes/127-rake-in-background – baash05 Mar 15 '12 at 00:44
-
8try this >> `system "rake task_name"` – Bongs Sep 11 '12 at 07:31
-
Ryan Bates covers [a couple of ways](http://railscasts.com/episodes/127-rake-in-background) in RailsCasts Episode #127. – Simone Carletti Jul 23 '09 at 07:35
-
1@Bongs yes you are right, this working well with me, system('rake task_name') – Astm Oct 08 '19 at 09:57
4 Answers
I agree with ddfreynee, but in case you know what you need code can look like:
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
You can require 'rake' and .load_tasks in an initializer instead.

- 1,485
- 14
- 13
-
-
@pxdleif It's in `config/application.rb` as the module name about 12 lines down, assuming you're using Rails. – Tim Fletcher Oct 03 '12 at 14:38
-
2
-
2This works great! Just so it's clear for others, this method is for synchronous calling of rake tasks (page does not render until rake is done). For async usage, use call_rake from this rails cast: http://railscasts.com/episodes/127-rake-in-background – benathon Nov 20 '13 at 12:27
-
Actually after a bit more work, my app on Rails 3.2.13 only needed the Sample::Application.load_tasks line. If i include the Task.clear line my app works until I call the first rake, then it gives me an error about a custom override I made for doc:app. But that's just my app – benathon Nov 20 '13 at 13:03
-
-
Is this open as new thread? I've added in my controller and task is initialized but controller function will not respond untill rake task completed. – faisal bhatti Sep 13 '18 at 13:37
I don't find it good style to call a rake task in code. I recommend putting the code for the task that you want to execute somewhere outside a rake task, and have the rake task call this code.
This not only has the advantage of being easy to call outside rake (which is what you want), but it also makes it much easier to test the rake task.

- 2,213
- 15
- 18
-
6+1 I concur: this is a perfect example of things that should be refactored and called in two different ways. – James A. Rosen Jul 23 '09 at 12:29
-
7http://railscasts.com/episodes/127-rake-in-background Seems an excellent reason to run a rake.. – baash05 Mar 15 '12 at 00:40
-
4Where would a good "somewhere" be for "somewhere outside the rake task"? – user456584 May 31 '13 at 14:59
-
@user456584 if it's related to models, put it in the model class. if it's related to something else, create a new file that holds them. – Aug 31 '13 at 15:57
-
Service Objects. https://blog.engineyard.com/2014/keeping-your-rails-controllers-dry-with-services – max Jul 22 '15 at 02:01
-
2In my case I needed to run a task from a 3rd party lib, so I couldn't refactor it (without going through the trouble of forking, etc) – César Izurieta Jul 29 '15 at 18:40
-
@ddfreyne What about if your services are tasks **with dependencies**? Doesn't it make sense to use rakes dependency management inside of your rails app instead of writing an own implementation? – Alexander Presber Dec 27 '16 at 20:46
Instead of trying to call a rake task in a controller, call a service objects that contains whatever logic you are trying to execute.
class SomeController < ApplicationController
def whatever
SomeServiceObject.call
end
end
...and then, assuming you are talking about a custom rake task, have it call the service object as well:
namespace :example do
desc 'important task'
task :important_task do
SomeServiceObject.call
end
end
In case you are not familiar with service objects, they are just plain old ruby classes that do a specific job. If you are trying to call some of the default rake tasks (ie: db:migrate) I would highly recommend not doing that sort of thing from a controller.

- 284
- 2
- 7
-
1
-
This concept is very straight forward. it works great! I am not adding code in `SomeServiceObject`. I am writing in model with `self` and calling from rake task like this: `User.subscribe_to_fcm` – mahfuz Apr 14 '21 at 06:56
You can do this in your controller:
%x[rake name_task]
with: name_task
is the name of your task
-
2
-
5
-
21@Duke when you answer or comment can you also explain your reasoning and not just make an assertion (that a controller in production shouldn't call rake tasks)? This would help people understand your reasoning instead of just knowing what you wouldn't do (but not hearing your explanation as to why). – Matt May 17 '13 at 00:59
-
7@Matt shelling out means that Rake will execute in another process. This means it will launch a new ruby interpreter. It's also a possibility that injection can occur which leads to arbitrary commands being executed (a few typos away from doing that). – Aug 31 '13 at 15:57