26
Checking under the Checking under the Hood: Hood: A Guide to Rails A Guide to Rails Engines Engines Mike Perham Mike Perham http://mikeperham.com http://mikeperham.com

Checking under the Hood: A Guide to Rails Engines Mike Perham

Embed Size (px)

Citation preview

Page 1: Checking under the Hood: A Guide to Rails Engines Mike Perham

Checking under the Checking under the Hood:Hood:A Guide to Rails EnginesA Guide to Rails Engines

Mike PerhamMike Perham

http://mikeperham.comhttp://mikeperham.com

Page 2: Checking under the Hood: A Guide to Rails Engines Mike Perham

MeMe

data_fabric - sharding for ActiveRecorddata_fabric - sharding for ActiveRecord

memcache-client - ships in Rails 2.3memcache-client - ships in Rails 2.3

Page 3: Checking under the Hood: A Guide to Rails Engines Mike Perham

Remember 2004?Remember 2004?

Page 4: Checking under the Hood: A Guide to Rails Engines Mike Perham
Page 5: Checking under the Hood: A Guide to Rails Engines Mike Perham

Rails Application?Rails Application?

Ruby codeRuby code

Initializes RailsInitializes Rails

Conforms to Rails’s MVC conventionsConforms to Rails’s MVC conventions

Page 6: Checking under the Hood: A Guide to Rails Engines Mike Perham

Remember 2006?Remember 2006?

Page 7: Checking under the Hood: A Guide to Rails Engines Mike Perham

Rails Plugins, thenRails Plugins, then

script/plugin listscript/plugin list

script/plugin install <url>script/plugin install <url>

Page 8: Checking under the Hood: A Guide to Rails Engines Mike Perham

Rails Plugin, nowRails Plugin, now

A gem which has A gem which has rails/init.rbrails/init.rb

Activated via Activated via config.gem ‘gem_name’config.gem ‘gem_name’

PLUGIN_ROOT/libPLUGIN_ROOT/lib is added to load_paths is added to load_paths

Page 9: Checking under the Hood: A Guide to Rails Engines Mike Perham

PluginsPlugins

Can:Can:

provide arbitrary classes, monkeypatch provide arbitrary classes, monkeypatch Ruby/RailsRuby/Rails

Can’t:Can’t:

Do MVC (controllers, views, routes, Do MVC (controllers, views, routes, migrations, ...)migrations, ...)

Page 10: Checking under the Hood: A Guide to Rails Engines Mike Perham

Loading Rails...Loading Rails...

Ruby has $LOAD_PATHRuby has $LOAD_PATH

require ‘foo’require ‘foo’

Rails has:Rails has:

Dependencies.load_pathDependencies.load_path

ActionController::Routing.controller_pathsActionController::Routing.controller_paths

ActionController::Base.view_pathsActionController::Base.view_paths

ActionController::Routing::Routes.add_configuration_filActionController::Routing::Routes.add_configuration_filee

Page 11: Checking under the Hood: A Guide to Rails Engines Mike Perham

Remember 2009?Remember 2009?

Page 12: Checking under the Hood: A Guide to Rails Engines Mike Perham

Rails Engine (2009)Rails Engine (2009)

Just a plugin with additional MVC hooksJust a plugin with additional MVC hooks

Effectively becomes another application!Effectively becomes another application!

Page 13: Checking under the Hood: A Guide to Rails Engines Mike Perham

Engines and MVCEngines and MVC

app/viewsapp/views added to the view template load added to the view template load pathpath

app/controllersapp/controllers added to the controller load added to the controller load pathpath

app/{models,helpers}app/{models,helpers} added to the load added to the load pathpath

Note: Application code always wins!Note: Application code always wins!

Page 14: Checking under the Hood: A Guide to Rails Engines Mike Perham

ModelsModels

Rails will look for models in the engineRails will look for models in the engine

No way to add MigrationsNo way to add Migrations

Beware of name collisionsBeware of name collisions

Use modules to namespaceUse modules to namespace

Foo::UserFoo::User, not , not UserUser

Page 15: Checking under the Hood: A Guide to Rails Engines Mike Perham

Engine SetupEngine Setup def configure_engines if engines.any? add_engine_routing_configurations add_engine_controller_paths add_engine_view_paths end end

def add_engine_routing_configurations engines.select(&:routed?).collect(&:routing_file).each do |routing_file| ActionController::Routing::Routes.add_configuration_file(routing_file) end end

def add_engine_controller_paths ActionController::Routing.controller_paths += engines.collect(&:controller_path) end

def add_engine_view_paths # reverse it such that the last engine can overwrite view paths from the first, like with routes paths = ActionView::PathSet.new(engines.collect(&:view_path).reverse) ActionController::Base.view_paths.concat(paths) ActionMailer::Base.view_paths.concat(paths) if configuration.frameworks.include?(:action_mailer) end

Page 16: Checking under the Hood: A Guide to Rails Engines Mike Perham

ControllersControllers

Rails will look for controllers in Rails will look for controllers in ENGINE_PATH/app/controllersENGINE_PATH/app/controllers

Routes are installed from Routes are installed from ENGINE_PATH/config/routes.rbENGINE_PATH/config/routes.rb

Engine helpers are NOT loaded with helpers :allEngine helpers are NOT loaded with helpers :all

Page 17: Checking under the Hood: A Guide to Rails Engines Mike Perham

ViewView

Rails will search for View templates in the Rails will search for View templates in the engineengine

Static assets (JS/CSS/images) need to be Static assets (JS/CSS/images) need to be copied to copied to RAILS_ROOT/publicRAILS_ROOT/public

Page 18: Checking under the Hood: A Guide to Rails Engines Mike Perham

MiscMisc

Rake tasks are loaded from Rake tasks are loaded from ENGINE_PATH/lib/tasksENGINE_PATH/lib/tasks

Use Use ENGINE_PATH/rails/init.rbENGINE_PATH/rails/init.rb or create a Rake or create a Rake task to bootstrap static files and migrations task to bootstrap static files and migrations

install.rb only run with script/plugin install...install.rb only run with script/plugin install...

Page 19: Checking under the Hood: A Guide to Rails Engines Mike Perham

Example init.rbExample init.rb

require 'fileutils'

def copy_static_assets src = File.join(File.dirname(__FILE__), '..', 'public') FileUtils.cp_r src, RAILS_ROOT if File.exist? srcend

def copy_migrations FileUtils.cp_r Dir.glob(“#{File.dirname(__FILE__)}/../db/migrate/*.rb”), File.join(RAILS_ROOT, 'db', 'migrate')end

copy_static_assetscopy_migrations

Page 20: Checking under the Hood: A Guide to Rails Engines Mike Perham

LimitationsLimitations

Change management of those static filesChange management of those static files

Page 21: Checking under the Hood: A Guide to Rails Engines Mike Perham

Notable EnginesNotable Engines

Clearance - authenticationClearance - authentication

http://github.com/thoughtbot/clearancehttp://github.com/thoughtbot/clearance

Queso - dynamic searchQueso - dynamic search

http://github.com/mperham/quesohttp://github.com/mperham/queso

Page 22: Checking under the Hood: A Guide to Rails Engines Mike Perham

QuesoQueso

Looks just like a normal Looks just like a normal app!app!

Page 23: Checking under the Hood: A Guide to Rails Engines Mike Perham

QuesoQueso

Page 24: Checking under the Hood: A Guide to Rails Engines Mike Perham

QuesoQueso

Page 25: Checking under the Hood: A Guide to Rails Engines Mike Perham

ConclusionConclusion

An Engine is:An Engine is:

a Rails application within your appa Rails application within your app

a plugin with MVC hooksa plugin with MVC hooks

Page 26: Checking under the Hood: A Guide to Rails Engines Mike Perham

Thank you!Thank you!http://mikeperham.comhttp://mikeperham.com

@mperham@mperham

Questions?Questions?