0

I'm using the excellent twitter-bootstrap-rails gem. There is a helper within that gem (NavbarHelper) which is used to generate Bootstrap navbars with a Ruby helper. I want to monkey patch the gem such that the dropdown lists won't have carets.

So, I looked into the source and found the relevant method here. All I have to do is override it. I created a new file in config/initializers called navbar.rb with the following content:

NavbarHelper.module_eval do
  def name_and_caret(name)
    "HELLO WORLD"
  end
end

Presumably, all of the dropdown titles then should be rendered as "HELLO WORLD" in my app (as referenced by the gem source). However, this is not occurring, and the gem does not appear to be monkeypatched at all.

I tried placing puts NavbarHelper.methods - Object.methods in the initializers file, and there were no results, which makes me think that Rails is not loading the gem correctly before the initializers. I have also checked and verified that the gem is not using autoload for its helpers.

Edit

What may be complicating this is the fact that my Gemfile includes the gem in the following manner:

gem 'twitter-bootstrap-rails', git: 'git://github.com/seyhunak/twitter-bootstrap-rails.git', branch: 'bootstrap3'

I'm not sure if this specific versioning means the monkeypatching doesn't work.

Edit #2

It seems there is only one version of the gem on my system, so I don't think that's the issue. Also, I have tried placing require 'twitter-bootstrap-rails at the top of the initializers file, with no results.

element119
  • 7,475
  • 8
  • 51
  • 74
  • try monkey-patching in a more straight forward manner - `module NavbarHelper\ndef name_and_caret(name)\n...\nend\nend`... Also make sure you `require` `navbar_helper` _before_ running this code. – Uri Agassi Apr 26 '14 at 08:15
  • @UriAgassi I tried that method, but it did not work. Also, I'm not sure about that require syntax, but I have tried requiring the gem at the top of the file but that didn't work either. – element119 Apr 26 '14 at 13:27

1 Answers1

1

The problem is that you patch the method on this module but the module already got included at this point. Try to define this in your application_helper.rb

def name_and_caret(name)
  super("blub #{name}")
end
2called-chaos
  • 3,018
  • 3
  • 21
  • 29
  • This works! Two questions. (1) If this is defined in application_helper, how does Ruby know that this method is part of the NavbarHelper module? – element119 Apr 26 '14 at 15:32
  • (2) How come in this instance the module already got included? Existing monkeypatching solutions work like so: http://stackoverflow.com/a/17220421/353878 – element119 Apr 26 '14 at 15:33
  • (1) it doesn't, both modules get included into the actionview instance (2) classes are a bit different than modules and including modules is different than inheriting from a class. Patching in ruby can be quite tricky. I don't understand it completely :) Helpful: [which method do I really call?](http://blog.bmonkeys.net/2014/how-i-debug#which-method-do-i-really-call?) – 2called-chaos Apr 26 '14 at 18:56
  • Ah, I didn't know that they are included in that way. Thanks. – element119 Apr 26 '14 at 20:53