53

Can I use helper methods in rake?

Max Wallace
  • 3,609
  • 31
  • 42
Sam Kong
  • 5,472
  • 8
  • 51
  • 87

2 Answers2

75

Yes, you can. You simply need to require the helper file and then include that helper inside your rake file (which actually a helper is a mixin that we can include).

For example, here I have an application_helper file inside app/helpers directory that contains this:

module ApplicationHelper
  def hi
    "hi"
  end
end

so here is my rake file's content:

require "#{Rails.root}/app/helpers/application_helper"
include ApplicationHelper

namespace :help do
  task :hi do
    puts hi
  end
end

and here is the result on my Terminal:

god:helper-in-rake arie$ rake help:hi 
hi
Maciej Biłas
  • 1,966
  • 2
  • 18
  • 20
Arie
  • 1,115
  • 1
  • 11
  • 19
  • 4
    Beware, by using `include` within rake, you inadvertently pollute the scope of `Object`, which succumbs all subsequently imported rake tasks to sharing the same methods. – random-forest-cat Apr 16 '14 at 06:00
  • 1
    What do you mean by subsequently imported rake tasks? As in rake tasks from other .rake files would also have access to the ApplicationHelper methods? – Mic Fok Oct 18 '14 at 17:51
  • 1
    It's been said and said, but it can't be said enough... you *really* shouldn't do this, especially in a Rails app (which use Rake extensively). It messes with the global `Object`, which can have far-reaching effects that can be extremely hard to track down. Just lost two hours to this... – nrser Sep 27 '17 at 15:50
20

As lfender6445 mentioned, using include ApplicationHelper, as in Arie's answer, is going to pollute the top-level scope containing your tasks.

Here's an alternative solution that avoids that unsafe side-effect.

First, we should not put our task helpers in app/helpers. To quote from "Where Do I Put My Code?" at codefol.io:

Rails “helpers” are very specifically view helpers. They’re automatically included in views, but not in controllers or models. That’s on purpose.

Since app/helpers is intended for view helpers, and Rake tasks are not views, we should put our task helpers somewhere else. I recommend lib/task_helpers.

In lib/task_helpers/application_helper.rb:

module ApplicationHelper
  def self.hi
    "hi"
  end
end

In your Rakefile or a .rake file in lib/tasks:

require 'task_helpers/application_helper'

namespace :help do
  task :hi do
    puts ApplicationHelper.hi
  end
end

I'm not sure if the question was originally asking about including view helpers in rake tasks, or just "helper methods" for Rake tasks. But it's not ideal to share a helper file across both views and tasks. Instead, take the helpers you want to use in both views and tasks, and move them to a separate dependency that's included both in a view helper, and in a task helper.

Max Wallace
  • 3,609
  • 31
  • 42
  • 1
    This solved it for me -- if you want to pass arguments to the helper method, you will be unable to do it unless you sort the scope out as you have done – Richard Peck Jun 21 '16 at 16:24
  • 4
    I'm wondering if it's a good idea to call it `application_helper.rb` as it might cause confusion. Maybe just `lib/task_helpers.rb` would be better. – Joshua Pinter Dec 20 '17 at 03:43