创建模块化应用程序

# 入门

首先,让我们生成一个新的 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 .

是的,现在我们可以摧毁任务!