定制自己的 Engine
Engine = Ruby gem + Rails MVC stack elements.
一,创建自己的 Engine
可用命令 rails plugin new 创建自己的 Engine.
常用可选参数 --full 或 --mountable
两者之间的区别,可以参考【Engine full vs mountable】章节。
拆分一下,步骤大概如下:
1) 继承于 Rails::Engine,一般把它们放在 lib/ 目录下。
# lib/my_engine.rb
module MyEngine
class Engine < Rails::Engine
# ... ...
end
end2) 在 config/application.rb (或 Gemfile) 里加载本文件。
Engine 相关的 model、controller 和 helper 会被加载到 app/ 里,route 会被加载到 config/routes.rb, locale 会被加载到 config/locales, tasks 会被加载到 lib/tasks.
# config/application.rb
require 'my_engine/engine'
# 或者
# Gemfile
gem 'my_engine', path: "/path/to/my_engine"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
最后更新于
这有帮助吗?