Inside of an initializer in Rails i am trying to include a module in a rails Model
User.send :include, Something
This works for the first request but does not for the second/third/etc. due to rails model reloading. I tried using ActionDispatch::Callbacks.to_prepare
(ActionDispatch::Callbacks.to_prepare, i'm using Rails 3.0.9)
ActionDispatch::Callbacks.to_prepare do
User.send :include, Something
end
but i keep getting a NoMethod error from a user instance when i try to call a method defined in my module module on the second/third/etc. request.
My question is this: Is there a way to reliably include a module into a Rails Model in an initializer without any development weirdness?
Update: Not Possible
Apparently this is impossible to do without middleware. If you disagree, add an answer below. This wasn't an acceptable solution for my use case, so I actually didn't even try it. Good luck.
Edit: Updated Debugging Info
I was playing around with the ActionDispatch::Callbacks.to_prepare
a bit more and i noticed something strange when i put this in my initializer:
ActionDispatch::Callbacks.to_prepare do
puts "to_prepare ==:#{User.object_id}"
end
and this in my controller
puts "controller ==:#{User.object_id}"
on the first request I get this:
to_prepare ==: 2297196200
controller ==: 2297196200
to_prepare ==: 2297196200
to_prepare ==: 2324202920
to_prepare ==: 2318560780
on the second request i get this:
to_prepare ==: 2326823900
controller ==: 2326823900
to_prepare ==: 2317901920
to_prepare ==: 2326746040
to_prepare ==: 2314369160
The first thing i noticed was the multiple calls to to_prepare which is weird. The second thing i noticed was in the first request (which works) the object_id directly before and after controller are called are the same, and they are not in any subsequent calls. If anyone could shed some light on why this is happening and how to get around it, it would be much appreciated.
Does using a
config.after_initialize
hook help? This is a development-environment-specific problem, due to class reloading taking place.The one thing that would almost certainly work would be to inject your module via a middleware, though it's difficult to know if that's a suitable solution for whatever you're doing.
Add it to the middleware chain with
config.middleware.use AddYourModuleMiddleware
, or alternatively by placinguse AddYourMiddleware
at the start ofApplicationController
.