Skip to content

Instantly share code, notes, and snippets.

@neerajsingh0101
Created December 15, 2010 15:36
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save neerajsingh0101/742099 to your computer and use it in GitHub Desktop.
~/action_dispatch/middleware/callbacks.rb has following code
def call(env)
_run_call_callbacks do
_run_prepare_callbacks if @prepare_each_request
@app.call(env)
end
end
def self.after(*args, &block)
set_callback(:call, :after, *args, &block)
end
~/rails/application/bootstrap.rb has following code
initializer :set_clear_dependencies_hook do
unless config.cache_classes
ActionDispatch::Callbacks.after do
ActiveSupport::DescendantsTracker.clear
ActiveSupport::Dependencies.clear
end
end
end
~/active_record/railtie.rb has following code
config.after_initialize do
ActiveSupport.on_load(:active_record) do
instantiate_observers
ActionDispatch::Callbacks.to_prepare(:activerecord_instantiate_observers) do
ActiveRecord::Base.instantiate_observers
end
end
end
All the above mentioned code does something like this.
When the app is served then there is an after callback which clears all
the dependencies.
Let's say I have UserObserver . This observer will ensure that User is
loaded and proper before_save/after_save callbacks are attached to
this class so that observer could be called.
Here is the code for reload
# reloads the environment
def reload!(print=true)
puts "Reloading..." if print
# This triggers the to_prepare callbacks
ActionDispatch::Callbacks.new(Proc.new {}, false).call({})
true
end
Notice that the app being passed is Proc.new {}. So when reload! is called
then UserObserver is loaded which loads User. Proper callbacks are set
on User and then app.call is done which does nothing. And then
Dependencies.clear is called which clears the User. Now when
you load User then User gets loaded but this User does not have the
observer hooks baked into it.
So why does this issue come up in reload! and not when console is
loaded the first time.
When console is loaded firs time then app.call never happens. In that
case @app.load_console is executed. Here @app is Rails.application.
When reload! is called then full lifecycle is executed and part of lifecycle
is calling Dependencies.clear.
What is the fix?
I don't really know. I changed code from this
def reload!(print=true)
puts "Reloading..." if print
#ActionDispatch::Callbacks.new(Proc.new {}, false).call({})
true
end
to
def reload!(print=true)
puts "Reloading..." if print
Rails::Console.start(Rails.application)
true
end
and everything works. The only issue is that everytime
you do reload! you are nesting into a new IRB console so you
need to do more than one exit to get out of console.
Not a good fix. May be JV or someone else will have better solution.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment