Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a simple Rails 3 text helper Gem [duplicate]

I've been working on my first Rails 3 plugin, to package up a simple helper function that I like having in the ApplicationHelper of all my apps. You can see the whole code on Github.

Here's my first attempt:

## lib/semantic_id.rb ##

require 'semantic_id/version'

module ::ActionView::Helpers::TextHelper

  def semantic_id
    string = String.new

    case
    when controller.action_name =~ /new|edit/
      string += controller.action_name + "_"
    when controller.action_name =~ /index|create/
      string += controller.controller_name
    else
      string += controller.controller_name.singularize
    end

    string += "_view"
  end

end

Now, this works, but as I understand it this is not the 'Rails 3 Way' of extending ActiveSupport or any other Rails module. I haven't been able to find much documentation on how you're "supposed" to build a Rails 3 gem. I tried following the Rails Guide, but the method given there for adding helpers didn't work, or else I was missing something.

My question is: given the code above as an example of the functionality I'm looking for, how would you turn this into a Rails 3 plugin Gem?

Thanks!

like image 697
Andrew Avatar asked Jul 01 '11 18:07

Andrew


Video Answer


1 Answers

The problem with what you've done is that you've bound your gem's functionality to ActionView. It would be better to make it more generic.

To fix this you should package your code in its own module and then inject that module into your view environment. For example, put your helper into its own module (and file):

# lib/semantic_id/helper.rb

module SemanticId
  module Helper
    def semantic_id
      ...
    end
  end
end

Then add it to ActionView using a Railtie:

# lib/semantic_id.rb

require 'semantic_id/helper'

ActiveSupport.on_load(:action_view) do
  include SemanticId::Helper
end

You want to separate the functional part of the helper from the part that inserts it into the framework. Your method contains some Rails-specific code, but if it didn't this technique would allow you to use it with Sinatra and other frameworks as well.

In general, the guts of your project should be in lib/<project_name>/*.rb, and lib/<project_name>.rb should just make the functionality accessible.

like image 71
Alex Reisner Avatar answered Oct 10 '22 22:10

Alex Reisner