Gem dependencies in Rails Engines - ruby-on-rails

I have followed the Getting Started with Engines in Rails documentation and I have set up an api engine in engines directory. According to the paragraph 6.6 Other Gem Dependencies one is supposed to define the gem dependencies in engines/my_api/my_api.gemspec file and that is pretty much what I did:
s.add_dependency "responders", "2.0"
After adding
`gem 'my_api', path: "engines/my_api"`
to the applications Gemfile and running bundler, everything looks as expected:
bundle install | grep responders
Installing responders 2.0.0
In the next step I set up a root path with a corresponding controller etc. and go to engines/my_api/app/controllers/my_api/application_controller.rb and add following content:
module MyApi
class ApplicationController < ActionController::Base
respond_to :json
end
end
I start the rails server, go the root url and guess what? I get following message:
The controller-level respond_to' feature has been extracted to the responders gem. Add it to your Gemfile to continue using this feature: gem 'responders', '~> 2.0' Consult the Rails upgrade guide for details.
As suggested in the error message, I've added the gem to the applications Gemfile, run bundle install and everything works as expected.
As far as I understood, engines are supposed to be self contained rails apps. From a self contained app I would at least expect to correctly resolve its dependencies. I assume that I am just doing something wrong and I hope someone will be able to help me to tackle down the problem, why do I have to explicitly specify the gem in the applications Gemfile?
EDIT:
Forgot to mention the versions:
$ gem list | grep rails
coffee-rails (4.1.0)
jquery-rails (4.0.3)
rails (4.2.1)
rails-deprecated_sanitizer (1.0.3)
rails-dom-testing (1.0.6)
rails-html-sanitizer (1.0.2)
sass-rails (5.0.3)
sprockets-rails (2.2.4)

As you observe, the gem is included in your bundle whether it is in your application's Gemfile or not. The difference is that when Bundler.require is called during application initialisation it only auto requires the gem's in your application's Gemfile - not indirect dependencies.
If your gem requires the responders gem gem to be loaded then it should require it explicitly - for example at the top of my_api.rb

Related

Rails gemfile version constraint issue

I have installed two versions of devise gem on my local machine namely devise(3.5.1) and devise(3.5.2).
In my gemfile i have included devise gem with pessimistic version constraint as shown below.
gem 'devise' , '~> 3.4'
dependencies for devise gem:
devise-encryptable-0.2.0 (devise (>= 2.1.0))
devise_invitable-1.4.0 (devise (>= 3.2.0))
devise_invitable-1.3.6 (devise (>= 3.2.0))
devise_security_extension-0.8.4 (devise (>= 2.0.0))
devise_security_extension-0.8.3 (devise (>= 2.0.0))
devise_security_extension-0.8.1 (devise (>= 2.0.0))
devise_security_extension-0.8.0 (devise (>= 2.0.0))
As per my research the meaning of this operator(~>) is that it will look for devise version >= 3.4 but <4.0 . But whenever i do bundle show in my project home directory it gives me error as "Could not find devise-3.4.1 in any of the sources".
My question is why bundle show command is giving an error if there is devise gem version >= 3.4 is available and installed on my machine(in my case devise version 3.5.2).
Your Gemfile is locked on this version thats why your bundle install command will not look for a different version try run bundle update devise then Rails will try to look for a newer version of devise gem and update your dependency.
understand the operator ~>:
when you add new gem into your Gemfile bundler have to take in account that you have dependency then the operator ~> come into action it will try to find the completable version for all the gems listed in your Gemfile and will not be locked to specific version it will be locked to a range of version lower then the first digit.
understand bundle install:
bundle install command look for gems listed in Gemfile.lock and will not update OR change any gem version no matter which operator is in your Gemfile.

Two separately namespaced Gemfiles in one Rails app?

I need to require these two gems in my Rails 3.2 app:
gem 'google-adwords-api'
gem 'netsuite'
However, they conflict on the versions of the savon gem. Bundler spits out this:
Bundler could not find compatible versions for gem "savon":
In Gemfile:
google-adwords-api (>= 0) ruby depends on
google-ads-common (~> 0.2.0) ruby depends on
savon (~> 0.9.1) ruby
netsuite (= 0.2.6) ruby depends on
savon (2.3.3)
I absolutely need both gems in my project, so this is what I've tried so far. I've moved the google-adwords-api gem into a custom Rails Engine I named "adx_interface" and mounted it within my Rails app. This engine has it's own Gemfile. If I put this line in my Rails app's Gemfile, then the Bundler error remains:
gem "adx_interface", "0.0.1", :path => "#{File.expand_path(__FILE__)}/../vendor/adx_interface"
Is there some way to namespace this engine so that it's dependencies aren't clashing with the apps dependencies? I've tried excluding the gem "adx_interface" line from the apps Gemfile, but that means I would have to start requiring gems manually instead of relying on Bundler. Is that a viable solution? If so, how do I go about including the google-adwords-api in such a way that it's namespaced properly and it's savon won't clash with netsuite's savon?
For what it's worth, I've personally contacted the author of the google-adwords-api gem. He said he likes the savon 0.9.1 gem and has no plans to ever update to a newer version.
What you are trying to do is exactly against the idea behind Bundler. Bundler exists to help you manage your dependencies and discover conflicts.
There is no clean way to bypass this restriction. The only solution I can think about, is to fork the google-adwords-api gem, bump the dependency and have your Gemfile to point to your custom fork.

Conflicting gem dependencies for the same gem. ruby depends on refinerycms-core

I created a new app in Refinery CMS and followed the instructions according to their guide. http://refinerycms.com/download
But when I go to run rails server, I get errors about gem dependencies. Normally those are easy to fix. But what to do when you have conflicting dependencies? This is one of the errors that I got
Bundler could not find compatible versions for gem "refinerycms-core":
In Gemfile:
refinerycms-blog (~> 2.0.0) ruby depends on
refinerycms-core (~> 2.0.0) ruby
refinerycms (~> 2.1.0) ruby depends on
refinerycms-core (2.1.0)
when I have ran into this problem in the past and I added the specific gem, it then would still give me an error saying that it needed the other gem as well. What am I doing wrong here?
Got a response on Twitter from the people at refinery who sent me this link
https://github.com/refinery/refinerycms/issues/2386#issuecomment-22978992
which says so change the gem to
gem 'refinerycms-blog', github: 'refinery/refinerycms-blog', branch: 'master'

no such file to load -- rack/openid

I am working on a rails gem which depends on rack/openid. But when I require it and fire up my application I get this error
no such file to load -- rack/openid
The gem is installed
$ gem list | grep openid
rack-openid (1.3.1, 1.2.0)
ruby-openid (2.1.8)
I've seen this question but it did NOT helped a lot.
Problem with require rack/openid in Rails 3 [native require work properly]
PS: I can require it from Irb just fine
It looks like you haven't added your Gem to the Gemfile, or you haven't added rack-openid as a dependency to your gem.
When Rails starts up, it uses bundler to set up the load path to match the Gemfile.lock file, so even a gem is installed locally you won't be able to require it if it isn't listed there.
Gemfile.lock is created by bundler based on the gems listed in Gemfile and their dependencies.
Make sure the gem you're working on specifies rack-openid as a dependency in its .gemspec, and then add gem 'my-gem-name' to your applications Gemfile (replace my-gem-name with whatever your gem is actually named).

Why is 'bundle update' installing ancient gems?

Everything was working just fine until, out of the blue, bundle update decided to 'update' to some very old versions of some gems. Any ideas? I'm baffled!
The Gemfile doesn't specify a version for the awry gems. eg.
gem 'rails'
I do...
bundle update
And(!)...
Using rails (0.9.5)
If I specify a version. eg.
gem 'rails', '~> 3.0'
Then it's ok.
Using rails (3.0.7)
Source 'http://rubygems.org'
Gem version 1.8.3, rvm version 1.6.14
Only some gems are wrong. mongoid is another. It's on 1.0.6. Thanks!
Problem solved. It was a gem conflict. I boiled it down to...
With just these two gems:
gem 'rails'
gem 'i18n'
You get i18n 0.6.0 (the latest) but rails is on 3.0.5 (3.0.7 is current latest).
And then with just these three:
gem 'rails'
gem 'i18n'
gem 'delayed_job'
You get:
Gems included by the bundle:
* actionmailer (0.6.1)
* actionpack (1.4.0)
* activerecord (1.6.0)
* activesupport (3.0.7)
* bundler (1.0.13)
* daemons (1.1.3)
* delayed_job (2.1.4)
* i18n (0.6.0)
* rails (0.9.5) <-- Yikes! that brings back memories!
* rake (0.9.0)
I've not looked deeper into how bundler's gem dependencies work yet, but that was what caused it. Interesting! And of course there's no need to include the i18n gem anyway, so removing that fixes things (or specifying gem versions).
Try this one.
Just update your bundler, May be of any-one of the older gem is conflicting with latest one, this type of issues arises.
'gem install bundler'
and then 'bundler install'
If you find again error, then delete GEM.lock file, then run bundler install. It may resolve the issue.

Resources