Reuse your project with rails engine - part 1
这片文章的核心是在同类项目中快速重用一个小型的项目文件,包括view,controller,model等等,同时也可以很容易的去重载它们。在part 2中,我会尝试提供一种helper的重用机制,另外会描述删除engine的namspace,也就是说不再使用Hr::
。
How to create a Namespace Less Engine
Imagine that we have HR system that could be reused in different companies' projects.
$ rails plugin new hr --full
$ rails g resource hr/department name
$ rails g resource hr/employee first_name last_name department:references
$ rake db:migrate
Comment out the table_name_prefix
in /app/models/hr.rb
. Because I don't want my table names to end up being like hr_departments
, hr_employees
.
module Hr
def self.table_name_prefix
# 'hr_'
end
end
Do the same things for routes, so that the urls aren't scoped under /hr
.
Rails.application.routes.draw do
resources :employees
resources :departments
end
Add placeholder models & controllers, so that we could write code without Namespace. And this also makes sure that we could define a Department, which inherits Hr::Department in our project, to override the default behavior.
class DepartmentsController < Hr::DepartmentsController
end
class EmployeesController < Hr::EmployeesController
end
class Department < Hr::Department
end
class Employee < Hr::Employee
end
Add a default behavior to Department
class Hr::Employee < ActiveRecord::Base
def full_name
[first_name, last_name].join(" ")
end
end
To test the Engine in the Dummy project.
$ cd test/dummy/
$ rails s
Reuse Hr Engine for Kude company
Create a new project, Kude:
$ rails new kude
In the Gemfile of Kude:
gem 'hr', :path => "../hr"
# change to the path to the hr engine
bundle
# to install the engine
$ rake hr_engine:install:migrations
$ rake db:migrate
$ rails s
An example to override the Hr::Employee, to make the full_name return in Chinese style. Note that you should define this in your project.
class Employee < Hr::Employee
def full_name
[last_name, first_name].join("")
end
end
# test it out
rails c
Hr::Employee.new(first_name: "少坤", last_name: "伍").full_name
=>
少坤 伍
Employee.new(first_name: "少坤", last_name: "伍").full_name
=>
伍少坤