创建模块化应用程序
# 入门
首先,让我们生成一个新的 Ruby on Rails 应用程序:
rails new ModularTodo
下一步是生成引擎!
cd ModularTodo && rails plugin new todo --mountable
我们还将创建一个引擎文件夹来存储引擎(即使我们只有一个!)。
mkdir engines && mv todo ./engines
发动机,就像宝石一样,带有 gemspec 文件。让我们放一些真正的值来避免警告。
#ModularTodo/engines/todo/todo.gemspec
$:.push File.expand_path("../lib", __FILE__)
#Maintain your gem's version:
require "todo/version"
#Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "todo"
s.version = Todo::VERSION
s.authors = ["Thibault Denizet"]
s.email = ["bo@samurails.com"]
s.homepage = "//samurails.com"
s.summary = "Todo Module"
s.description = "Todo Module for Modular Rails article"
s.license = "MIT"
#Moar stuff
#...
end
现在我们需要将 Todo 引擎添加到父应用程序 Gemfile。
#ModularTodo/Gemfile
#Other gems
gem 'todo', path: 'engines/todo'
我们来运行 bundle install
。你应该在 gem 列表中看到以下内容:
Using todo 0.0.1 from source at engines/todo
好的,我们的 Todo 引擎正确加载! 在我们开始编码之前,我们还有最后一件事要做:安装 Todo 引擎。我们可以在父应用程序的 routes.rb 文件中执行此操作。
Rails.application.routes.draw do
mount Todo::Engine => "/", as: 'todo'
end
我们将它安装在/
,但我们也可以在/todo
上访问它。由于我们只有一个模块,/
很好。
现在,你可以启动服务器并在浏览器中进行检查。你应该看到默认的 Rails 视图,因为我们还没有定义任何控制器/视图。我们现在就这样做!
建立 Todo 列表
我们将在 Todo 模块中构建一个名为 Task
的模型,但要从父应用程序正确迁移数据库,我们需要在 engine.rb
文件中添加一个小的初始化程序。
#ModularTodo/engines/todo/lib/todo/engine.rb
module Todo
class Engine < ::Rails::Engine
isolate_namespace Todo
initializer :append_migrations do |app|
unless app.root.to_s.match(root.to_s)
config.paths["db/migrate"].expanded.each do |p|
app.config.paths["db/migrate"] << p
end
end
end
end
end
就是这样,现在当我们从父应用程序运行迁移时,Todo 引擎中的迁移也将被加载。
让我们创建 Task
模型。需要从引擎文件夹运行 scaffold
命令。
cd engines/todo && rails g scaffold Task title:string content:text
从父文件夹运行迁移:
rake db:migrate
现在,我们只需要在 Todo 引擎中定义根路由:
#ModularTodo/engines/todo/config/routes.rb
Todo::Engine.routes.draw do
resources :tasks
root 'tasks#index'
end
你可以玩它,创建任务,删除它们……等等,删除不起作用! 为什么?! 好吧,似乎没有加载 JQuery,所以让我们将它添加到引擎内的 application.js
文件中!
// ModularTodo/engines/todo/app/assets/javascripts/todo/application.js
//= require jquery
//= require jquery_ujs
//= require_tree .
是的,现在我们可以摧毁任务!