问题
As I understand it, plugins are not reloaded in Rails with each request in development mode. Which makes sense, as generally you add plugins to your app and it's the app you're developing.
But if you are developing a plugin, you have to restart the server with each change to the plugin which has a significant overhead.
Is there any way to make Rails reload your plugin during development, the way it reloads your models and controllers?
回答1:
If restarting the server automatically when plugin code changes is an acceptable solution, you could use Mike Clark/topfunky's rstakeout for that, or the newer watchr which sounds like it does the same thing.
You would do something like this:
rstakeout 'touch tmp/restart.txt' 'vendor/plugins/**/*'
回答2:
I have been struggling with this for some time, too. None of the solutions work, including the autoload_paths
and autoload_once_paths
tricks. Furthermore, the hack with FileUpdateChecker
and initializers also does not help (the checker triggers properly, but the files are not reloaded). Same for config.reload_plugins = true
...
However, there is a solution. In app/controllers/application_controller.rb
add one line:
require_dependency 'your_file_name_here'
The application controller is reloaded on every request and require_dependency
makes your file to be checked for modifications and reloaded accordingly. It worked for me, Apache 2, Passenger 3 and Rails 3.0.3.
回答3:
I do this by using the shotgun gem.
gem install shotgun
cd /path/to/rails/app
shotgun
slower response time, but reloading all the rails code, not wasting time to write autoload_paths
回答4:
Easy way, develop your plugin in a folder inside the "app" folder:
- app
- models
- controllers
- helpers
- views
- your_plugin_here
This way, all your plugin classes will be reloaded on each request.
Another possibility is to add the path at your application.rb file:
require File.expand_path('../boot', __FILE__)
require 'rails/all'
Bundler.require(:default, Rails.env) if defined?(Bundler)
module SunspotTutorial
class Application < Rails::Application
config.autoload_paths += %W{ #{config.root}/plugins/your_plugin_name/lib }
#lots of other code
end
end
This way your plugin is going to be reloaded all the time.
回答5:
With https://github.com/ranmocy/guard-rails, it's super easy:
# Gemfile.local
gem 'guard-rails'
$ bundle
$ guard init rails
# Guardfile:
guard 'rails' do
watch('Gemfile.lock')
watch(%r{^(config|plugins)/.*})
end
$ bundle exec guard
回答6:
This solution, for engines, works on Rails 2.3 but comes with one cavaet, it will load all files in the engine and parent app on every request which will make response times slower.
# lib/my_engine/engine.rb
if ENV['RELOAD_MYENGINE'] && Rails.env.development?
config.to_prepare do
Rails.logger.debug "RELOADING MY ENGINE"
require_dependency MyEngine::Engine.root.join('lib', 'my_engine').to_s
end
config.after_initialize do
Rails.application.config.reload_classes_only_on_change = false
end
Then start the server:
RELOAD_MYENGINE=1 rails server
来源:https://stackoverflow.com/questions/4713066/how-can-i-force-my-plugin-to-reload-with-each-request