4

I am writing a gem which provides helpers for views. The HTML I want to insert via the helper is complex enough that I'd rather write it in a _partial.html.erb file. How do I get the gem's view path include in the application's load_path?

Note: the only gem I've found that does something like this is Devise. When a view cannot be found, Rails prints the load path which (on my machine) looks like:

Missing partial sortable_nested_set/tree with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html], :locale=>[:en, :en]} in view paths "/home/jason/VirtualRestaurant3/app/views", "/home/jason/.rvm/gems/ruby-1.9.2-preview3/gems/devise-1.1.rc0/app/views"

How does Devise do it?

My gem: http://github.com/jrmurad/SortableNestedSet Devise gem: +http://+github.com/plataformatec/devise

Jason
  • 681
  • 1
  • 9
  • 19

1 Answers1

4

If you put the 'app' directory in the base directory of your plugin, Rails will add app/views to the view path by default.

.
├── app
│   └── views
│       └── plugin_name
│           └── _my_partial.html.erb

Then you can render the partial from your plugin's helper method with:

render :partial => "plugin_name/my_partial"

Note that Rails doesn't make the views available by default in the plugin test environment. To Include them there add the following to test/test_helper.rb:

ActionController::Base.prepend_view_path File.dirname(__FILE__) + "/../app/views"
Steve
  • 1,084
  • 11
  • 17
  • I can't seem to get this to work for the life of me. I've got a gem (locally right now) called 'admin_site' which has the directory structure shown above, with 'admin_site' in place of the `plugin_name`; I've got it installed on my local Rails site using Bundler (pointing to the gem locally, that is) but asking for the template at `admin_site/common/index` (which is where it is in the gem) fails with `ActionView::MissingTemplate`, and I don't see my gem in the template search path list (I only get my Rails site's views, Devise's views, and the root of my site). – Ben Kreeger Sep 14 '11 at 16:59
  • 1
    Found it out… I had to include an `.rb` file that's the main entry point for the gem with a `class Engine < Rails::Engine` class. – Ben Kreeger Nov 10 '11 at 20:59
  • Wondering what version of Rails you were on.. having a devil of a time with a similar problem (my Rails 2.3.5 is not finding views in the gem i'm developing in /app/views, and adding your 'class Engine < Rails::Engine' gets me `load_missing_constant':NameError: uninitialized constant Rails::Engine) :-/ – ilasno Apr 27 '12 at 00:42
  • 1
    FYI: AFAIK Rails::Engine is a Rails 3 thing. – reto Jun 26 '12 at 15:15
  • FYI: The load paths are set on the launch of the rails server, so if you have added an app/views directory, make sure to restart your rails server! – Daniel Apr 09 '14 at 23:37