Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Rails Engines. Doing It Wrong. And Then Right.
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Robert Glaser
October 13, 2011
Programming
280
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rails Engines. Doing It Wrong. And Then Right.
Robert Glaser
October 13, 2011
More Decks by Robert Glaser
See All by Robert Glaser
RAG: The Architecture of Reliable AI
youngbrioche
0
110
Dein Produkt braucht nicht mehr Technik, sondern mehr Produkt
youngbrioche
3
550
Die Unbenutzbarkeit von Enterprise Web-Anwendungen
youngbrioche
0
81
Stop flying blind. Profiling your App's Internals.
youngbrioche
3
530
Bootstrapping & Boilerplating
youngbrioche
9
370
Travis CI
youngbrioche
4
350
Modern Web Development with Ruby on Rails
youngbrioche
2
340
Other Decks in Programming
See All in Programming
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
3
2.3k
[DroidKnights 2026] Workflow AX: From Auto-Documented Policies to E2E Testing
raeminkang
0
260
[2026-10-14](C)Re:ゼロから始める異世界生活〜始まりの終わりと終わりの始まり〜
tosite
0
250
Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / lets learn vue custom renderer by making 3d library
drumath2237
1
110
ChromeでローカルLLM
ryu1013
0
190
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
6.1k
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.5k
Web Framework Benchmark Battle 2026, Any%
a_matsuda
3
3.1k
Next.js: The final boss of Web Performance
guaca
0
380
プロジェクトコードをキレイキレイしよう!暗黙的な参照を読み解く静的解析
ostk0069
0
200
AI Augmentation Techniques with Liberty
ivargrimstad
0
250
Inertia Rails: The One-Person Framework with React & Friends
skryukov
0
200
Featured
See All Featured
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
420
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
440
Fireside Chat
paigeccino
43
4.1k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
480
4 Signs Your Business is Dying
shpigford
187
23k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
550
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
600
How GitHub (no longer) Works
holman
316
150k
Darren the Foodie - Storyboard
khoart
PRO
4
4.1k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
960
The Language of Interfaces
destraynor
162
27k
Transcript
Rails Engines. Doing it wrong. And then right.
None
@mrreynolds
Why Engines? Extend your app with reusable models, controllers, views,
helpers, routes, locales and tasks.
It‘s an app within an app.
Rails::Engine < Rails::Railtie
What‘s a Railtie? • Core of the framework • Provides
hooks to extend Rails • ActiveRecord, ActionController etc. are all Railties
What is an Engine then ?
It‘s just a Railtie with some defaults.
Typical cases • CMS • Admin Frontend • Translation Frontend
Our problem • Build a vocabulary and thesauraus management system
• Adjust and extend it for every customer without forking it
github.com/innoq/iqvoc
First approach • iQvoc as main app • Vendor logic
as engine
The problem • Could not act as a standalone app
• Always had to be plugged into a main app
Second approach • Vendor logic as main app • iQvoc
as engine (and app)
The problem • A Rails 3.0 Engine can not act
as a standalone app by default (requires customization) • No out-of-the-box support for migrations, assets etc.
Options
Wait for Rails 3.1
Just hack it.
What do you need ?
Act as an engine… # lib/engine.rb module Iqvoc class Engine
< Rails::Engine end end
…only if we want to # config/initializers/iqvoc.rb unless Iqvoc.const_defined?(:Application) require
File.join(File.dirname(__FILE__), '../../lib/engine') end # config/application.rb module Iqvoc class Application < Rails::Application
Up next: Engine tasks # lib/engine.rb class Engine < Rails::Engine
paths.lib.tasks << "lib/engine_tasks" Only available when app is mounted as an engine!
What about Migrations? namespace :iqvoc do namespace :db do task
:migrate => :environment do ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true path = Iqvoc::Engine.find_root_with_flag("db").join('db/migrate') ActiveRecord::Migrator.migrate(path, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby end end end
None
Rails 3.1 rake railties:copy_migrations
Routes Foo.application.routes.draw do Rails.application.routes.draw do
Rails 3.1 # Main app Rails.application.routes.draw do mount Foo::Engine =>
"/foo" end # Engine Foo::Engine.routes.draw do …
Rails 3.1 Namespace isolation module MyEngine class Foo < Rails::Engine
isolate_namespace Foo end end # Separate routers for each Engine foo.root_path main_app.root_path
If you isolate, don‘t forget to move things.
app/controllers/foo/things_controller.rb app/views/foo/things/new.html.erb …
Assets task :link do Iqvoc.for_static_folders do |source_common_dir, target_common_dir| File.unlink(target_common_dir) if
File.symlink?(target_common_dir) && ENV['force'] == "true" if !File.exists?(target_common_dir) puts "Linking #{source_common_dir} -> #{target_common_dir}" File.symlink(source_common_dir, target_common_dir) else puts "Symlink #{target_common_dir} already exists!" end end end
Rails 3.1 # ActionDispath::Static config.serve_static_assets = true or rake railties:create_symlinks
bundle in hell • No support for multiple locations of
a single gem
Forget about that: group :development do gem 'iqvoc', :path =>
'../iqvoc' end group :production do gem 'iqvoc', :git => '
[email protected]
:innoq/iqvoc.git' end
Forget about that as well:
None
Instead: Separate your Gemfiles
Rails 3.0 Engines Rails 3.1 Engines Rails 2.3 Engines
Engines = Mountable Apps
None
@drogus Piotr Sarnacki Say thanks to:
Thanks!