# Solved: plugin models unloading after first request

**URL:** <https://www.ruby-forum.com/t/solved-plugin-models-unloading-after-first-request/149383>\
**Category:** Engines\
**Created:** [September 24, 2008, 11:09am UTC](https://www.ruby-forum.com/t/solved-plugin-models-unloading-after-first-request/149383 "2008-09-24T11:09:36Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![elijah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/2bfe46/32.png) [@elijah](https://www.ruby-forum.com/u/elijah)\
**Post date:** [September 24, 2008, 11:09am UTC](https://www.ruby-forum.com/t/solved-plugin-models-unloading-after-first-request/149383/1 "2008-09-24T11:09:36Z")

</div>

I haven’t been able to find this advice anywhere else, so I am posting  
here so that it may help another lost soul.

Some plugins have a problem: if a plugin applies a mixin directly to a  
model in app/models, this mixin gets unloaded by rails after the first  
request. This only happens in development mode. The symptom of this is  
an application that works for the first request but fails on subsequent  
requests.

A call to Dispatcher.to\_prepare will get around this problem by  
re-applying any mixin that modifies the core models on each request. In  
production mode, the classes are not unloaded and so the mixin is only  
applied once.

“Normal” plugins don’t have this problem: they modify active record, and  
then the core models call these extensions. When these core models are  
reloaded by rails, the plugin code is then reloaded as well. The problem  
only shows up when you want to modify a model in apps/model without  
requiring any code change to that model.

This style of using plugins is not considered to be a good idea by many.  
However, I am writing plugins that are designed exclusively for a  
particular application. These plugins enable optional features of a  
specific application–they do not try to modify the behavior of rails or  
extend active record.

## Here is the code:

(1) modify Engines:Plugin

require ‘dispatcher’

Engines::Plugin.class\_eval do  
def apply\_mixin\_to\_model(model\_class, mixin\_module)  
Dispatcher.to\_prepare {  
model\_class = Kernel.const\_get(model\_class.to\_s) # \ weird, yet  
mixin\_module = Kernel.const\_get(mixin\_module.to\_s) # / required.  
model\_class.send(:extend, mixin\_module.const\_get(“ClassMethods”))  
model\_class.send(:include,  
mixin\_module.const\_get(“InstanceMethods”))  
model\_class.instance\_eval &(mixin\_module.class\_definition())  
}  
end  
end

(2) in your plugin’s init.rb:

# in this case, there is a model app/models/language.rb, and module

# vendor/plugins/myplugin/app/models/language\_extension.rb

apply\_mixin\_to\_model(Language, LanguageExtension)

(3) this is what my language\_extension.rb looks like:

module LanguageExtension  
module ClassMethods  
end

module InstanceMethods  
def percent\_complete()  
count = Key.count\_all  
if count \> 0  
(Key.translated(self).count / count \* 100.0).round.to\_s + ‘%’  
end  
end  
end

def self.class\_definition  
lambda {  
has\_many :translations, :dependent =\> :destroy  
}  
end  
end

* * *

Most the code in apply\_mixin\_to\_model is not really required. But it  
seemed to me a little repetitive to type this over and over again for  
each mixin:

module MyModule  
def self.included(base)  
base.extend(ClassMethods)  
base.instance\_eval do  
include InstanceMethods  
has\_many :somethings  
…  
end  
end  
…  
end

So, most the code in apply\_mixin\_to\_model is just doing that repeated  
stuff for you, so long as the submodules are named right (ie  
InstanceMethods, etc).

The simple thing to do is just put:

Dispatcher.to\_prepare {  
Language.send(:include, LanguageExtension)  
}

In the plugin’s init.rb. But again, I am trying to get fancy, perhaps at  
my own peril.

Hope that helps someone,  
-elijah

---

<div class="post-metadata">

**Author:** ![elijah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/2bfe46/32.png) [@elijah](https://www.ruby-forum.com/u/elijah)\
**Post date:** [November 17, 2008, 9:22am UTC](https://www.ruby-forum.com/t/solved-plugin-models-unloading-after-first-request/149383/2 "2008-11-17T09:22:39Z")

</div>

I cannot thank you enough for posting this. Have you found a more  
elegant way to handle this?
