简体   繁体   English

“常规”Ruby gem或Rails引擎?

[英]“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. 我的Rails应用程序(Rails 3和4的编译)都有自己的数据库(自然),但也访问第三方数据库。 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. 但由于它有Rails“部件”,这似乎表明我需要一个引擎。 But the fact that I want these models in all my apps seems to point to just needing a "normal" rails-compatible gem. 但是我想在所有应用程序中使用这些模型这一事实似乎只需要一个“正常”的rails兼容宝石。

Would it be better to do this as a gem or as a Rails engine? 将它作为gem或Rails引擎更好吗?

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. 从我读过的一些指南中,似乎你在一个新的Rails应用程序上创建了一个引擎。 I'm also a little unclear on full vs. mountable , but I do know I'd like these models in their own namespace. 我对fullmountable也有点不清楚,但我知道我希望这些模型在他们自己的命名空间中。

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 . 最简单的是,“引擎”是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). 一旦它被Rails应用程序加载(例如require 'yourgem/engine ), require 'yourgem/engine的方法就会执行并将引擎连接到Rails应用程序(包括将引擎内的一堆路径神奇地附加到应用程序的负载路径,这是您的引擎模型和控制器加载到您的应用程序的方式)。

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. 现在,如果您已经尝试阅读Rails Engines入门 ,您可能会认为除非使用Rails生成器,否则无法创建引擎,并坚持使用Rails约定,以及所有这些。 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. 我个人建议创建一个普通的gem并将其转换为引擎,主要是通过阅读API文档 ,这些文档更加实际。 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). 甚至可以覆盖在gem中拥有app文件夹的建议模式,以保存模型和控制器等等(请参阅API文档中的Paths部分)。

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: 你的engine.rb非常简单:

# 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! 希望有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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