I'm writing a rails engine that has some dependencies. I've specified the dependencies in the gemspec and the engine is finding them when I run bundle install
(i.e. Gemfile.lock looks correct). When I want to use the plugin in a Ruby file, I can do so but need to explicitly require dependency-name
at the top of the file.
However, when I want to use the dependency's asset pipeline, sprockets can't find it.
The app I'm using (for now) is the dummy app that comes in a rails plugin's test folder. Sprockets can find the assets if I specify them in the engine's Gemfile (which is really the dummy app's Gemfile), but not if I specify them in the gemspec. I don't want to rely on the Gemfile because that means that any app that uses my plugin will need to manually add all my dependencies to their Gemfile. For the same reason I don't want a solution that involves updating the app's config file.
This works (in a ruby file) when dependency is included from gemspec:
require 'dependency-name'
but this (in a JS file) doesn't work when dependency is included from gemspec:
//= require 'dependency-name'
Neither require
is needed when dependency is included from Gemfile. I think it's pretty clear but let me know if you need more specifics.
You designed your engine according to the http://edgeguides.rubyonrails.org/engines.html ? If your engine class inherits from Rails::Engine, it really should find all assets by itself.
I needed to include the dependency explicitly in my engine.rb in order for its assets to end up in my asset pipeline. Not sure why this is necessary, as Alastor's answer sounded correct to me. It's worth noting that the dependencies are gems that I created using bundler, though I don't see why that should make a difference.
Added 11/23/12
Having spent some more time working with Engines, I think I understand this more fully now. Gemspecs are just of a list of dependencies that are required, but the gemspec doesn't instruct the application, on startup, to load the files from those dependencies. Gemfiles, on the other hand, do load all the files during startup.
Added 3/20/2015
My statement from over 2 years ago that "Gemfiles, on the other hand, do load all the files during startup" is not entirely true. It's mostly true in Rails, which by default runs
Bundler.require
to require all dependencies listed in the Gemfile, as shown in the generator file here -- note that while the default behavior of Rails changed from Rails3 to Rails 4 as discussed here, both useBundler.require
. However, there is a strong case to be made for usingBundler.setup
and then an explicitrequire "dependency1"
in whichever file actually depends ondepedency1
. See this discussion ofBundler.require
versusBundler.setup
.Also, as @nruth points out in the comments, this may lead to loading of unnecessary classes. However, if the dependency is well designed, its classes will mostly be autoloaded, creating minimal overhead for requiring the entire dependency. Alternatively, if it defines its engine in a file that can be required in in isolation, you can just include the engine file, which should add the necessary files to your asset path, allowing you to require its assets in your CSS & JS manifests. See this bootstrap-sass example, where the gem both adds all its assets to
config.assets.paths
and adds some of them toconfig.assets.precompile
.While this question is a few years old and I don't even remember what Rails Engine I was writing at the time, I suspect the right way to do it would have been closer to this:
But note that this should not be necessary--the dependency itself should have defined this initializer so that simply requiring it would be sufficient, as the bootstrap example above does.