建立模組化應用程式

# 入門

首先,讓我們生成一個新的 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 .

是的,現在我們可以摧毀任務!