简体   繁体   中英

“Regular” Ruby gem or Rails engine?

My Rails apps (compilation of Rails 3 and 4) all have their own database (naturally), but also access a 3rd-party database. As such, they have models to this 3rd-party database. I want to DRY up these models to be reusable instead of copy-pasting them in each app. There are no controllers, helpers, or routes to consider; only models. But since it has Rails "parts", this would seem to indicate I need an engine. But the fact that I want these models in all my apps seems to point to just needing a "normal" rails-compatible gem.

Would it be better to do this as a gem or as a Rails engine?

If an engine is better, I'm not quite sure where to start. From some of the guides I've read, it seems as though you create an engine on a fresh Rails application. I'm also a little unclear on full vs. mountable , but I do know I'd like these models in their own namespace.

Finally, I would want these models usable in all my apps. Engines can be packaged up as a gem, correct? If so, then couldn't I just start off as a gem, instead of starting as an engine inside one particular app and then exporting the gem after the fact?

I'm quite confused, so any feedback is appreciated. I've also never built a gem nor an engine before, so please forgive any stupidity in this area.

Engines aren't actually that magical, although it's easy to get that impression. At their simplest, an "engine" is a just subclass of Rails::Engine . As soon as it gets loaded by your Rails app (eg require 'yourgem/engine ), the methods in your engine execute and hook up your engine to the Rails application (including magically appending a bunch of paths inside your engine to the applications' load paths, which is how your engine's models and controllers get loaded into your app).

Now, if you've tried reading Getting Started With Rails Engines , you're probably thinking you can't create an engine unless you use the Rails generators, and stick to the Rails conventions, and all that. But all that is optional! I personally recommend creating a normal gem and turning it into an engine, largely just by reading the API docs , which are much more down-to-earth. Even the recommended pattern of having an app folder in your gem, to hold your models and controllers or whatnot, can be overridden (see the Paths section in the API docs).

So in your case, where you want your engine to just contain models, I'd suggest a gem layout like so:

yourgem/
  app/
    models/
      yourgem/
        your_thing.rb
  db/
    migrate/
      20160413010101_create_models.rb
  lib/
    yourgem/
      engine.rb
      version.rb
    yourgem.rb
  yourgem.gemspec

Your engine.rb can be pretty simple:

# lib/yourgem/engine.rb
module YourGem
  class Engine < ::Rails::Engine
    isolate_namespace YourGem # this is generally recommended

    # no other special configuration needed. But maybe you want
    # an initializer to be added to the app? Easy!
    initializer 'yourgem.boot_stuff_up' do
      YourGem.boot_something_up!
    end
  end
end

And your migration and models will look normal (though remember your model has to be scoped under your gem name, to avoid conflicts with whatever app may use this engine).

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM