I am trying to extend a model from engine 1 with a concern from engine 2 through an app initializer, but I'm getting some weird behavior, here's what I've got:
Concern
module Engine2
module Concerns
module MyConcern
extend ActiveSupport::Concern
included do
puts "Concern included!"
end
def jump
puts 'Jumping!!!!'
end
end
end
end
Initializer
require 'engine2/my_concern'
module Engine1
class Member
include Engine2::Concerns::MyConcern
end
end
When I boot up the application, I see as expect the Concern included!
message in the console, and the Member
class can call the method jump
, but as soon as I change any code in the host app I get the following error:
NoMethodError (undefined method 'jump' for #<Engine1::Member:0x007fe7533b4f10>)
and I have to reload the server, then it works fine again until I make another change in the host app, then it throws the error again, why is this happening and how can I avoid it?
Is there a better place where I should perform the class opening to include the concern instead of the initializer?
So I finally figured it out, basically what happens is that in development mode every model is reloaded on every code change but the initializers are only ran once at startup of the server, so once the code changes in the controller, the model is reloaded but doesn't include the concern anymore and therefore breaks.
I solved it by moving the code of the initializer to a to_prepare
block in the application.rb
.
For those who don't know, to_prepare
adds a preparation callback that will run before every request in development mode, or before the first request in production.