views:

324

answers:

4

Being lazy (and liking DRY code), I'm the kind of guy who's going to write a few little wrappers for recurring HTML markup. Those provided by Rails are good already, but sometimes I have something a little more specific that I know I'm going to repeat over and over.

In some situations a partial can be the solution, but sometimes I'm just going to call the snippet way too often to justify the overhead of using partials.

Right now I create a helpers/html_helper.rb file and stick them in there. The problem is that helpers are not reloaded dynamically per request during development. So each time I tweak my snippet or the code around it, I have to kill the server and restart it.

Granted, it's just a 5 seconds process, but I love Rails' convenience of just developing and then refreshing the browser. So I'd love to have that for my markup snippets as well.

Note: Just sticking 'unloadable' inside the helper module doesn't work.

A: 

It's not a real solution but you could use tests (TestUnit, RSpec or whatever) to make sure your helpers work as expected. That way, you wouldn't rely on automatic reloading of your helpers so much.

Christoph Schiessl
+1  A: 

Good question! This is a technique I should abuse more frequently.

    #I go in environment.db (presumably it will work in one of the per-environment files, too.)
    Dependencies.explicitly_unloadable_constants << 'NameOfHelperToReloadHere'

That array starts out empty, incidentally, at least in my install. (Checked via console.)

I tested this locally and it works for me, at least on Rails 2.0.2. Major credit for the solution belongs to this gentleman.

Patrick McKenzie
It works! Thanks for the tip :-)Note that in 2.1.1, using Dependencies directly is deprecated and should be replaced by ActiveSupport::Dependencies
webmat
Hmmm, I spoke too fast. For some reason it doesn't seem to work with helpers. I'll keep digging.
webmat
That article ends with the weirdest comment ever :-) Check it out!
webmat
A: 

If you stick them in application_helper.rb they'll be loaded every time and be available for all of your views. This is loaded every time in development mode (or at least I haven't encountered any issues).

I typically will create little helpers that I use throughout the site (sortable table headers for instance) that use the same logic.

Steropes
+1  A: 

This should reload ALL helpers on every request (assuming you've stuck to the default naming conventions)

#Put this in config/environments/development.rb
ActiveSupport::Dependencies.explicitly_unloadable_constants.concat(Dir.glob("#{RAILS_ROOT}/app/helpers/**/*.rb").map {|file| File.basename(file, '.rb').camelize})

Or if you are using an older version of Rails (2.0.2 or earlier I think)

#Put this in config/environments/development.rb
Dependencies.explicitly_unloadable_constants.concat(Dir.glob("#{RAILS_ROOT}/app/helpers/**/*.rb").map {|file| File.basename(file, '.rb').camelize})

Works for me in RoR 2.1.1


Update: modified top snippet to include 'ActiveSupport::', must have copied / pasted incorrectly from my code.

Daniel Beardsley
I tried exactly that. It still doesn't pick up new modifications made to a helper between refreshes. Btw, both your snippets say exactly the same thing ;-)
webmat