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
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
65
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
3Dシーンの圧縮
fadis
1
680
CSC307 Lecture 17
javiergs
PRO
0
320
ユニットテストの先へ:テスト技法で要求・仕様を整理するJava開発実践 / Beyond_Unit_Testing_Practical_Java_Development_Techniques_for_Organizing_Requirements_and_Specifications
shimashima35
0
370
Oxcを導入して開発体験が向上した話
yug1224
4
290
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
310
net-httpのHTTP/2対応について
naruse
0
460
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.3k
タクシーアプリ『GO』の バックエンド開発のおける AI利活用と若者のすべて
pyama86
3
1.9k
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
160
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
110
Spring Security 実践 ─ GraphQL APIで実務に役立つ 認証・認可 を学ぶ
wagyu
0
200
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
4.8k
Featured
See All Featured
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
330
Skip the Path - Find Your Career Trail
mkilby
1
140
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
160
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1.1k
Designing for Timeless Needs
cassininazir
1
250
Un-Boring Meetings
codingconduct
0
310
So, you think you're a good person
axbom
PRO
2
2.1k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
610
Mobile First: as difficult as doing things right
swwweet
225
10k
Between Models and Reality
mayunak
4
330
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
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!