I am using Ruby on Rails 3.2.9 and Ruby 1.9.3-p125. The scenario is the following:
I implemented a acts_as_customizable plugin and I have an Article model class “acting as customizable”. The plugin, through metaprogramming, adds a method named customize to a Comment model class (note: since that, the plugin has side effects because manipulate the Comment object outside the scope of the Article object).
Given that scenario, when I (re-)start the server and I run @comment.customize then I get the error NoMethodError - undefined method 'customize' for #<Comment:0x0...>. However, when I (re-)start the server and I run the following code then all works as expected:
Article
@comment.customize
If I understood the “evil” part, the above code works because the “simple” call to the Article class before to run the customize method makes it to fire the acts_as_customizable method which in turn adds (through metaprogramming) the customize method to the Comment class.
How should I avoid the “evil”?
This is caused by lazy/auto loading. To save time rails doesn’t load all classes on startup. Instead, it loads them when necessary. If you never access
Article, it’s not loaded and, therefore,Commentis not getting its dynamic methods.Simple answer: use
require_dependency(thanks, @cryo28)Correct answer: don’t do evil. Make plugin behaviour more predictable / less confusing. If it’s applied to
Article, it should act onArticleand notComment.