mac*_*iek 9 ruby rubygems ruby-on-rails bundler ruby-on-rails-3
我有Rails 3.0.x应用程序.我想在运行时加载gem,而不使用Gemfile
.
我想要完成的是像往常一样加载我的应用程序,由Bundler加载常规gem.之后我想加载位于特定目录中的所有gem(Rails Engines)(但直到运行时,我不知道那将是什么宝石).
有人知道这是否可以在Rails中使用,也许使用Bundler API?
你要做的是危险的.如果你的每个Rails引擎都是宝石 - 那么它们也会有其他依赖项的Gemfiles,而这些依赖项还有其他依赖项等.如果你允许Bundler解决这些问题,那么你在运行时会遇到较少的问题.
这是你如何做到没有任何黑客攻击.请记住,您Gemfile
只是Ruby代码,并且您可以拥有默认情况下未加载的gem.
# In your Gemfile, add at the end:
Dir[YOUR_RAILS_ENGINES_SUBFOLDER + "/*/*.gemspec"].each do |gemspec_file|
dir_name = File.dirname(gemspec_file)
gem_name = File.basename(gemspec_file, File.extname(gemspec_file))
# sometimes "-" and "_" are used interchangeably in gems
# for e.g. gemspec_file is "engines/my-engine/my_engine.gemspec"
# dir_name will be engines/my-engine
# gem_name will be my_engine
# Register that engine as a dependency, *without* being required
gem gem_name, :path => dir_name, :require => false
# e.g. this is similar to saying
# gem 'my_engine', :path => 'engines/my-engine', :require => false
end
Run Code Online (Sandbox Code Playgroud)
现在,您已将所有动态Rails引擎注册为gem依赖项.Bundler将解决它们及其所有子依赖关系,因此您不必担心任何事情.只需bundle install
在运行应用程序之前运行一次,或者在您添加/删除该文件夹中的任何引擎时运行.
好消息是,这些宝石只会被注册,而不会被加载.因此,在您的生产代码中,您现在只需通过说明即可加载您在运行时选择的任何gemrequire <your-engine-name>
编辑:额外的代码评论