Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
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
86
Dein Produkt braucht nicht mehr Technik, sondern mehr Produkt
youngbrioche
3
530
Die Unbenutzbarkeit von Enterprise Web-Anwendungen
youngbrioche
0
66
Stop flying blind. Profiling your App's Internals.
youngbrioche
3
510
Bootstrapping & Boilerplating
youngbrioche
9
360
Travis CI
youngbrioche
4
330
Modern Web Development with Ruby on Rails
youngbrioche
2
330
Other Decks in Programming
See All in Programming
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
770
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.3k
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
1
350
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
170
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
570
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
790
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
140
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
940
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2.3k
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
14
5.8k
Featured
See All Featured
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
300
Automating Front-end Workflow
addyosmani
1370
210k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
620
The Mindset for Success: Future Career Progression
greggifford
PRO
0
370
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
280
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
KATA
mclloyd
PRO
35
15k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
Claude Code のすすめ
schroneko
67
230k
GraphQLとの向き合い方2022年版
quramy
50
15k
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!