定制自己的 Engine
Engine = Ruby gem + Rails MVC stack elements.
一,创建自己的 Engine
可用命令 rails plugin new
创建自己的 Engine.
常用可选参数 --full
或 --mountable
两者之间的区别,可以参考【Engine full vs mountable】章节。
拆分一下,步骤大概如下:
1) 继承于 Rails::Engine,一般把它们放在 lib/ 目录下。
2) 在 config/application.rb (或 Gemfile) 里加载本文件。
Engine 相关的 model、controller 和 helper 会被加载到 app/ 里,route 会被加载到 config/routes.rb, locale 会被加载到 config/locales, tasks 会被加载到 lib/tasks.
3) 在 routes.rb 里 mount MyEngine::Engine
二,编写 my_engine/engine.rb 文件内容
每个 Engine 都会有自己的 engine.rb 文件。里面有自己的 Engine 类,它继承于 ::Rails::Engine
1) 常用方法之 config、initializer
在这文件里,你可以使用 config, initializer 等方法。这点和定制 Railtie 类似,但不同点是:当前 Engine 的配置和初始化,作用域仅限于当前 Engine.
config 是个方法,但同时它也是 Configuration 的实例对象,所以你可以使用 config.generators
:
还可使用 config.app_generators
:
2) 常用方法之 isolate_namespace
默认 Engine 和应用是在一个环境里的,这意味着应用所有 helper 和命名路由都可以在 Engine 里使用。
你可以使用 isolate_namespace
更改此项默认配置,将 Engine 和应用隔离出来。使用举例:
此时 MyEngine
和应用是隔离了的,假设 MyEngine 有代码:
此时 FooController 仅能使用 Engine
里提供的 helper,以及 MyEngine::Engine.routes
提供的 url helper.
另外一个改变就是 Engine 里的路由不必再使用 namespace,举例:
resources :articles 自动对应着 MyEngine::ArticlesController
. 并且不必使用长长的 url helper,例如 my_engine_articles_path
可以直接使用 articles_path
不受 isolate_namespace 影响的就是对于 model 的调用,仍然使用 engine_name 做为前缀。例如以下例子的 MyEngine::Article
另一个改变是对表名的更改。默认使用 engine_name (在这里是 "my_engine")做为表前缀,也就是说 MyEngine::Article 对应的表名应该是 my_engine_articles
3) 常用方法之 paths
Engine 默认都有自己的文件、目录结构,如果你没有定制,那么就使用默认的:
paths
通过它,可以更改默认的文件、目录结构。
举例,你想把 controller 文件放到 lib/ 目录下:
再或者,controller 在 app/ 和 lib/ 下都可接受:
Application 在 Engine 之上,它又有自己的配置和初始化。它配置了 app/ 下的文件、目录会被自动加载,所以像 app/services 会被自动加载。
4) 常用方法之 endpoint
Engine 内容也可以是一个 Rack Application. 当你的代码本身是 Rack Application,而又想使用 Engine 的特性时,可以这么做:
1) 在自己定义的 Engine 里,使用 endpoint
:
2) 和平常一样,在 route 里 mount
你的 Engine:
5) 常用方法之 middleware
Engine 内容也可以是一个 Middleware. 当你的代码本身是 Middleware,而又想使用 Engine 的特性时,可以这么做:
6) 常用方法之 engine_name
用几个场景可能会用到 engine name:
routes: 当你使用 mount(MyEngine::Engine => '/my_engine')
rake task: 当你使用 my_engine:install:migrations
Engine name 默认根据类名而来,如 MyEngine::Engine
对应有 my_engine_engine
. 你可以使用 engine_name
进行自定义:
三,编写 Engine 内容
做了上述两步后,就是编写内容。该做什么事,做什么事;该完成什么功能,完成什么功能。
四,在 main_app 引入定制的 Engine
也就是:
在 config/application.rb (或 Gemfile) 里加载本文件。 在 routes.rb 里 mount MyEngine::Engine
最后更新于