0

I have a higher level app, that includes two engines:

  • Core (engine)
  • API (engine)

The API engine depends on the models present in the Core engine. I was wondering how to reference these.


What I have tried

For example, if the Core engine has the model "User", how do I reference it via the API engine?

module Api
describe User do
routes { Api::Engine.routes }

before :each do
  ::Core::User.create!
end
....

With this code, I received:

 Failure/Error: ::Core::User.create!
 NameError:
   uninitialized constant Core

So I thought that I had to include the core engine in the api.gemspec file.

  s.add_dependency "core", path: "core/"

however, looks like bundler did not like that.

There was a Gem::Requirement::BadRequirementError while loading
api.gemspec:
Illformed requirement [{:path=>"core/"}] from myAppPath/api/api.gemspec:21:in

I also tried

s.add_dependency "core", path: "../core/"

but that gave me a similar error.

Any idea what should be done to reference the Core models from the API engine?

Thanks!

Update I attempted to add the Core engine into the Api engine via the Api's Gemfile. Unfortunately, I get an error. I'm starting to feel that engine's should not reference other engines. Would that be true?

/home/.rvm/gems/ruby-2.0.0-p247/gems/railties-
4.0.0/lib/rails/application/routes_reloader.rb:10:in `rescue in execute_if_updated': 
Rails::Application::RoutesReloader#execute_if_updated delegated to 
updater.execute_if_updated, but updater is nil: #
<Rails::Application::RoutesReloader:0x007fb53b67bce8 @paths=
["/home/myApp/api/spec/dummy/config/routes.rb", "/home/myApp/core/config/routes.rb", 
"/home/myApp/api/config/routes.rb"], @route_sets=[#
<ActionDispatch::Routing::RouteSet:0x007fb53b3b8420>, #
<ActionDispatch::Routing::RouteSet:0x007fb53b6008b8>, #
<ActionDispatch::Routing::RouteSet:0x007fb53b6b9b60>]> (RuntimeError)

UPDATE on findings In addition to the answer below, I would like to add that .gemspec files DO NOT have any information on where the gem will be stored, i.e. it will not point to a git repository, or a file path, etc. This is explained in this article:

http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/

Karan
  • 14,824
  • 24
  • 91
  • 157
  • add it to your API's gem file like gem "core", path: "path/to/core/". – Sachin Singh Aug 18 '13 at 03:27
  • as in to the Gemfile? yeah, I think that may be the way. I just tried that - got a different error, but I have a feeling this new error is unrelated. – Karan Aug 18 '13 at 03:34

1 Answers1

1

There are 2 things to understand here:

If your Engines are supposed to be public (like Devise engine for example), then you'll want to reference your Core dependency in the gemspec. You'll not be able to reference it using path though. But for public engines, this is not a matter since public engines will be on Rubygems at some point in time.

If your Engines are private and used only to cleanup your code base, then adding gem 'core', path: '../core' to your Engine's Gemfile is fine.

The thing to remember here:

  • gemspec is for dependencies declaration (the gems your engine needs in order to work)
  • Gemfile is for local or test dependencies declaration
Pierre-Louis Gottfrois
  • 17,561
  • 8
  • 47
  • 71
  • ok, thanks for the answer. I have a full blown 'app' rails app, and a 'api' engine, and a 'core' engine that lives under the 'app'. The 'api' depends on the 'core' engine, so would I have to add 'core' in the api.gemspec? If that's the case, I couldnt get it to work. – Karan Aug 18 '13 at 11:33
  • Both 'api' and 'core' gems are private, so I haven't published them on Rubygems (and hence I would need to use a path, but looks like a *.gemspec doesn't like paths ...) – Karan Aug 18 '13 at 11:36
  • btw - I added the core into my Gemfile, but as soon as I do that, I get some error. Any idea what it may be? – Karan Aug 18 '13 at 12:51