Forcing gem dependencies on host rails app - ruby-on-rails

I have an engine gem that uses slim templates within it's views. I also have a host rails application that uses erb templates and doesn't have slim rails in it's gemfile.
I'm trying to force the dependency of slim through the gem. It seems that you can render slim files into an erb file, although this is generally bad practice. As it stands, when:
add_dependency "slim-rails"
is added into the gemspec, it bundles slim-rails from the host app but I still get an error that it can't find the template because it's not looking for slim in the file types. In the end i've had to add 'slim-rails' to the host app, but the ideal solution would be for the dependency to work correctly.
Am i doing something wrong? The gem is currently implemented as a submodule that sits in the directory but the path is set correctly etc.

Related

Rails 5 Engine - Gems dependencies, how to load them into the application?

I'm having the same issue as this link but none of the solutions here are working. A couple hours of searching and of course reading the main Rails Engine docs have all turned up the same strategies as the SO link. I'm wondering if there is something different about the way Rails 5 handles dependencies.
I have this dependency in my gemspec:
s.add_development_dependency "pg_search"
I have this line in my engine.rb file:
require "pg_search"
When I run rails s from within the engine's directory, everything loads fine. When I mount the engine and try to start the server from the rails app directory, I get this error:
/home/andy/.rvm/gems/ruby-2.3.1/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:292:in `require': cannot load such file -- pg_search (LoadError).
Finally, if I add the pg_search gem to the Gemfile of the app that is mounting the engine, the rails server starts. This of course isn't a solution, I'm just trying to provide complete information.
This happened because I used 'add_development_dependency' rather than 'add_dependency'.

Installing Rails engine gem - path not found

I've been following the guide around rails engines here: http://guides.rubyonrails.org/engines.html and have created the example engine blorgh and also have a barebones rails app.
I generated my engine following this command:
rails plugin new blorgh --mountable
And I can confirm that I have: /lib/blorgh.rb in my engine. Now going by the guides it states you simply need to add the following to your main app:
gem 'blorgh', path: 'engines/blorgh'. Now in my main rails app when I try to do bundle install I get:
The path /Users/home/projects/unicorn/engines/blorgh does not exist.
I'm pretty sure I'm missing something basic here.
The path /Users/home/projects/unicorn/engines/blorgh does not exist
Because Rails application going to Search ‘engines’ folder that's stores the engines (even if you just have one!) in your case /engines/blorgh not found any engine.
The path option in Gemfile is for using gem that is on the path specified.
And it have to be the directory where the unpacked gem is located.
In your case it looked to engines/blorgh relative to your working directory. Which is on /Users/home/projects/unicorn/engines/blorgh.
And /Users/home/projects/unicorn/engines/blorgh is simply doesn't exists.
To fix it, make sure you put the engine on /Users/home/projects/unicorn/engines/blorgh

How do I import ruby gems assets to project? [duplicate]

I'm trying to wrap the bootstrap-sass gem inside another gem (let's call it my-engine). Along the way, I'm building a small Rails application to test things out. As a first step, I wanted to make sure I could get bootstrap-sass working directly in my Rails application. The Gemfile for the Rails app looks like this:
gem 'bootstrap-sass', '3.3.1.0'
gem 'my-engine, path: "~/dev/my-engine"
This works fine. The bootstrap assets are loaded into my Rails application and everything looks good. Now, I want to take bootstrap-sass out of my Rails app and let it load through my-engine. So, my Rails application Gemfile now looks like:
gem 'my-engine, path: "~/dev/my-engine"
The .gemspec for my-engine has:
spec.add_runtime_dependency 'bootstrap-sass', '3.3.1.0'
I can re-bundle the my-engine gem with no problems. I can re-bundle the Rails application with no problems. However, when I refresh the page of the Rails app, I get the following error:
File to import not found or unreadable: bootstrap-sprockets.
That break occurs when sprockets is trying to build the application.css file. Sometimes this will pass and I'll get a different error about missing the bootstrap.js javascript file when the application.js is being built.
Why is this happening? I'm wondering if it has something to with the fact that I'm developing the gems locally and haven't published them, although I'm not sure why that would affect bootstrap-sass which is published. I'm using bundler 1.5.3.
Make sure 'bootstrap-sass' is required in your engine. One sensible place to do this is in your lib/my-engine.rb file:
require 'bootstrap-sass'
Adding the bootstrap-sass gem as a runtime dependency in the .gemspec isn't enough when you're trying to wrap gems.
As you want to use more and more scss/js/coffeescript libraries, you may want to consider moving to bower vs gemfiles as the source for bootstrap-sass-official. We use bower-rails for rake tasks and auto-configuration. It's a really lite config/rake task layer over standard bower.
Addressing your answer, bootstrap problems via the gem was one of the reasons I switched our engine over to just bower assets. We now import bootstrap-sass-official and have full control, note however that for sass files you will need to import the longer path to the source file, i.e. in our engine _application.scss:
# our custom variable overrides
#import 'overrides/variables';
#import 'bootstrap-sass-official/assets/stylesheets/bootstrap-sprockets';
#import 'bootstrap-sass-official/assets/stylesheets/bootstrap';
NOTE: if you want your app sass variables to override engine and sass variables, make sure your engine has _application.scss not application.scss, the leading underscore is critical for variable context/scope.
Thinking ahead, you may need to ignore bower transitive dependencies as we did.
(i.e. some dependencies may use 'bootstrap' while others use 'bootstrap-sass-official' etc)
We use it like this in our .bowerrc such as the following:
{
"ignoredDependencies": [
"bootstrap",
"bootstrap-sass",
"bootstrap-sass-official"
]
}
In conclusion
We have been using this for several months with success. bower-rails will install the dependencies in /vendor/assets and if referenced in your engine, you won't need to reference them at all in your application project. It has been fast and easy to maintain/add/update libraries and know exactly how files are included.

Vendored assets in a Rails engine not loading when used as a Gem

Im writing an isolated Rails Engine which has it's own javascript in app/assets which in turn loads a bunch of dependencies that are kept in the engine's vendor/assets.
I've been using the dummy app in the test folder for development and everything has worked as I expect.
If I package the engine up as a gem and install it into a separate rails app, when I try to access the engine in a browser I get the Sprockets::FileNotFound exception couldn't find file.
If I fire up the console and have a look at Rails.application.config.assets.paths it includes mygem/app/assets but not mygem/vendor/assets.
This is where it gets weird. If I change the rails app's Gemfile and load the engine directly from a path, I don't have these problems. I can view my engine in browser without any Sprockets issues. Loading up the console and looking at Rails.application.config.assets.paths shows both path/to/mygem/app/assets AND path/to/mygem/vendor/assets.
I don't get this. Why would I get different behaviour if the engine is being loaded as a packaged gem or directly from a path?
Answering my own question. School-boy error, nothing to do with the asset pipeline, everything to do with adding the vendor path to the gemspec configuration.
s.files = Dir['{app,config,db,lib,vendor}/**/*', 'README.md', 'LICENSE.md']

Using another gem's javascript in a Rails Engine

I'm trying to create a rails engine that will use javascript from a gem dependency that I have added to the engine. However I keep getting "couldn't find file 'fullcalendar'" when I put the following line in my application.js for my engine:
//= require fullcalendar
This line is loading the javascript from the gem dependency into the rails engine.
This same line will work when the gem is installed on a normal rails app (not engine). What am I missing here? Can an engine load javascript from another engine/gem?
UPDATE:
Researching on my own the issue could be that sprockets only looks for javascript inside the engine. The gem dependency is installed into vendor/cache of the parent app NOT the engine therefore //require fullcalendar fails because it is looking within the engine and the javascript for fullcalendar is in the parent application.
What confuses me is that if I include fullcalendar in the parent application gemfile explicitly than I am able to access it in the engine. This doesn't make sense to me. In both instances the full calendar gems javascript is in the parent app, but the behavior is different. Including the gem in two places is unappelaing to me and doesn't seem like a proper solution. Any thoughts?
I had some trouble with this in the past.
App > Engine 1 > Engine 2
Engine 1 and Engine 2 worked fine on the app. I created a dummy app in Engine 1 to test Engine 2's functionality, also worked fine. But when I put Engine 1 in App it didn't work at all.
My big mistake here was only including Engine 1 in App, Engine 2 has to be included as well!
Inheritance does not work for Gemfiles, just dependencies.
A little late to the party, but I recently had the same issue. Here is my post to describe it the solution http://grantrklinsing.com/articles/2013/01/10/adding-3rd-party-assets-to-a-rails-gem.html. Hope it helps if you didn't get it working.
Does the fullcanendar gem you're using come with an installer? Some gems come with installers for model migrations, assets, views, config files, etc.
If you're referring to the fullcalendar-rails gem it comes with an installer that you have to run using the
rails g fullcalendar:install command.
If the gem doesn't come with an installer you can manaully clone the gem to your local machine by running git clone gem_github_repository_url_here.git which will enable you to navigate the gem's folders and you'll have direct access to any of the assets that the gem uses which can be copied over to your rails application.
If your Engine has a dependency added through the gemspec file, you need to require this dependency directly before Engine initialization.
app/lib/app/engine.rb
require 'fullcalendar-rails'
module App
class Engine < ::Rails::Engine
isolate_namespace App
end
end

Resources