• Things like Devise are very very COOL!!!!!!• But we just want to reuse our own projects• And we never will release it as a library for people to use
• we need something could be done in your lifeclass User < ActiveRecord::Base devise :database_authenticatable, :registerable, :rememberable, :trackable, :token_authenticatable, :validatable, :recoverable, :rememberable, :trackable, :validatableend• that code costs you >1 week, but you only got paid 100 RMB???????• and you have a whole projects to be rewritten in that way???????????????????????????????????
What we get for Namespace less?• reuse your projects (not just a small part of code) • for example, you are a site building company • you have copy/paste your cms, news system, fancy image uploader, wysiwyg editor, navigation conﬁg... • but every client just wants a fancy different looking...• easy to inherits & override anything • controllers Hey, I am still copy & paste. • models How is the Engine? • views? • helper• write code without namespace • MyAwsomeEngine::MyAwsomeModel • MyAwsomeModel I am still learning the Devise code structure.• something robust, not monkey hacking It just updates again...
• Add Namespace less placeholders for models & controllers• Do inline Namespace::ClassName deﬁnition• Write code without Namespace• That’s probably all...
in your engine:/app/models/department.rbin your project:/app/models/department.rb Which one will be used?
in your engine:/app/models/hr/department.rbin your project:/app/models/department.rbclass department < Hr::Departmentend To ﬁx it!
in your engine:/app/models/hr/department.rb/app/models/department.rbin your project:/app/models/department.rbclass department < Hr::Departmentend To ﬁx it, also make engine not complain!
module Hr class DepartmentsController < ApplicationController def index @departments = Department.all # Hr::Department end endendclass Hr::DepartmentsController < ApplicationController def index @departments = Department.all # Department endend
A model override sampleclass Hr::Employee < ActiveRecord::Base def full_name [ﬁrst_name, last_name].join(" ") # Shaokun Wu endendclass Employee < Hr::Employee def full_name [last_name, ﬁrst_name].join # 伍少坤 end
Controllers• The same as models...
What a about View?• You cannot inherits your view• But you could override them
Helper• Not so sure, perhaps something like... Module Hr::ApplicationHelper def hello_world; end end Module ApplicationHelper include Hr::ApplicationHelper def hello_world end end
Find a better place for the placeholder ﬁlesclass MyEngine < Rails::Engine paths["app/controllers"] << "lib/placeholders/controllers"end
How to use the engine• in your Gemﬁle gem hr, :path => "../hr"• then $ bundle install• copy the migration ﬁles $ rake hr_engine:install:migrations
Some Tips• add your engine as a submodule instead of a pure Gem • your engine is not perfect • bundle still cannot handle same name of gem in different group??• write engine rake task to generate models & controllers in your projects• try with mongoid, but be careful of the namespace • class Department < Hr::Department • # still get hr_departments as the collection name... • # of course, you could set the collection name in mongoid :)
Read this carefully• http://api.rubyonrails.org/classes/Rails/ Engine.html
The code here• https://github.com/shaokun/nl-engine