57

I have a set of rails view helpers that I use regularly, and would like to package them up into a gem, such that I could just put a line in my Gemfile, and have the helpers accessible from my views.

I have created gems before using Bundler, and Jeweler, however, I'm not all all clear on how to organize the Rails view helpers in a gem, and include them into rails.

I would appreciate any pointers, or links to up-to-date tutorials on how to do this for Rails 3

Thanks

Just to clarify: The question isn't on "how to create a gem". Its "how to package view helpers in a gem, so I can use them in Rails"

Edit 2: I also agree with the poster below.. A rails engine is waay too much overkill for this kind of (hopefully simple) requirement

noli
  • 15,927
  • 8
  • 46
  • 62

3 Answers3

97

In my opinion, a full Engine is overkill for this task. You could instead just create a Railtie which includes your helpers into ActionView::Base when it initializes.

# lib/my_gem/view_helpers.rb
module MyGem
  module ViewHelpers
    def pre(text)
      content_tag :pre, text
    end

    def another_helper
      # super secret stuff
    end
  end
end

# lib/my_gem/railtie.rb
require 'my_gem/view_helpers'
module MyGem
  class Railtie < Rails::Railtie
    initializer "my_gem.view_helpers" do
      ActiveSupport.on_load(:action_view) { include MyGem::ViewHelpers }
    end
  end
end

# lib/my_gem.rb
require 'my_gem/railtie' if defined?(Rails)
Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
  • Thanks, I'm going to try this.. will report back – noli Apr 26 '11 at 20:13
  • Hi, I want to know: why it named "Railtie", what does "Railtie" mean ? – why Jan 22 '13 at 06:57
  • @why Well, I don't know for sure, but I assume it's because it's the class with the hooks necessary to "tie" the code into "Rails" – Michelle Tilley Jan 22 '13 at 16:18
  • 4
    @why "Railties" are the wood slats that train rails are secured to, i.e. that "tie" them together. It's just a cutesy way to name a similar construct in RoR that is in keeping with the "rails" theme. – soupdog Jan 06 '14 at 02:03
  • 5
    @BrandonTilley if I could offer one recommendation, it would be to utilize the built-in load hook capabilities instead of calling the private method `include` on `ActionView::Base`. Rails has offered lazy load hooks as a part of ActiveSupport since [3.0.0](https://github.com/rails/rails/blob/v3.0.0/activesupport/lib/active_support/lazy_load_hooks.rb). Thus, the alternate code for the initializer block would look like `ActiveSupport.on_load( :action_view ){ include MyGem::ViewHelpers }` – cookrn Nov 19 '14 at 18:36
5

Also if you want include helper only for Rails3 version you can use

# lib/my_gem.rb
require 'my_gem/railtie' if defined?(Rails::Railtie)
timfjord
  • 1,759
  • 19
  • 20
3

What you are probably looking for is an engine. An engine is a gem that contains rails application pieces (in fact, a rails application is itself an engine.)

Mario
  • 2,942
  • 1
  • 25
  • 38