rails engines
DESCRIPTION
TRANSCRIPT
![Page 1: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/1.jpg)
Rails Engines
![Page 2: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/2.jpg)
Hi, I’m Josh
I work here ->
lvlsvn.com
![Page 3: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/3.jpg)
We Build Ruby AppsAnd a bunch of other stuff
![Page 4: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/4.jpg)
We also do design
![Page 5: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/5.jpg)
We also do design
The designers had NOTHING to do with my slides.
![Page 6: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/6.jpg)
Here’s the Problem
Even custom applications want to be able to manage their static pages
Think Contact Us, Team Bios, etc.
Wordpress, Drupal even Locomotive are great but heavy weight
![Page 7: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/7.jpg)
What we needed
A mini-cms
Uses our existing rails views
No subdomaining, feels like part of the app
Works with our authentication setup
Great for 4 or 5 pages of content
![Page 8: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/8.jpg)
OptionsHigh Voltage
https://github.com/thoughtbot/high_voltage
Great for devs, not great for the customer
Locomotive Engine
http://locomotivecms.com/
Awesome but heavyweight, assumes their template style
![Page 9: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/9.jpg)
Exstatic
https://github.com/LevelSeven/exstatic
WARNING: Not even close to finished
Works w/ devise
Mounts in another application
Inherits that application’s layouts
![Page 10: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/10.jpg)
But how?
Rails Engines
obviously, otherwise this talk wouldn’t make much sense
![Page 11: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/11.jpg)
What are Rails Engines?Lesser known feature, started in Rails 3.0
Mini-application that can be added to a larger rails app
Replace plugins
Are a subset of Railties, so you can use railtie stuff (like generators, rake tasks, etc.)
![Page 12: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/12.jpg)
Why?
Code reuse
Share functional components
Share business logic
Isolation
Distribution
Open Source part of a private app
![Page 13: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/13.jpg)
Creating an Engine2 Ways
Rails 3.1 or greater
> rails plugin new
Rails 3.0
Use enginex by Jose Valim
https://github.com/josevalim/enginex
![Page 14: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/14.jpg)
$> rails plugin new depot_engine --dummy-path=spec/dummy --skip-test-unit --mountable --skip-bundle
...
![Page 15: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/15.jpg)
--dummy-path=spec/
$>
rails plugin new depot_engine
dummy --skip-test-unit --mountable --skip-bundle
Creates a new Rails Engine with the name DepotEngine
![Page 16: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/16.jpg)
--dummy-path=spec/
$>
rails plugin new depot_engine --skip-test-unit --mountable --skip-bundle
Creates a fake rails app in the RSpec path
dummy
![Page 17: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/17.jpg)
--dummy-path=spec/
$>
rails plugin new depot_engine
--mountable
Sets the engine to be “mountable” as opposed to “full”
Full - the parent inherits routes from the engine and can directly access it’s components (controllers, models, etc.)
Mountable - the engine’s namespace is isolated and draws its own routes. It mounts at a path:
mount DepotEngine::Engine => “/store”, :as => “store”
dummy--skip-test-unit --skip-bundle
![Page 18: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/18.jpg)
![Page 19: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/19.jpg)
Setting Up RSpec
Add rspec-rails to development dependencies in gemspec
bundle install
rails g rspec:install
Set rspec as test_framework in engine.rb
lib/engine_name/engine.rb
![Page 20: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/20.jpg)
Testing through dummy rails plugin new automatically creates a dummy app
Rails.application is available to test initializers
Rails.application.routes will get you dummy app routes
More in a bit
![Page 21: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/21.jpg)
Depot as an Engine
Depot application
github.com/levelseven/depot_engine
![Page 22: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/22.jpg)
Migration Pitfalls
You have to use the engine name everywhere
rails g migration add_foo_to_engine_name_table_name
To copy migrations into dummy app cd into dummy and run
rake engine_name:install:migrations
![Page 23: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/23.jpg)
Asset Pipeline PitfallsAssets have to be preceeded by engine_name in view helpers
image_tag(‘engine_name/logo.png’)
Copy assets group in Gemfile from normal rails app into Gemfile in engine, then bundle install in dummy app
![Page 24: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/24.jpg)
View Hints
You can reference parent via main_app helper
i.e. link_to “Home”, main_app.root_path
Use the parent’s layouts by adding layout “application” to ApplicationController in engine
![Page 25: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/25.jpg)
View Hints
In parent app use engine_name.path_helper to link into engine
link_to “Store”, depot_engine.root_path
You can override views by putting them in
app/views/engine_name/controller/view_name
![Page 26: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/26.jpg)
Rake Tasks
Rake tasks can be added in lib/tasks
Show up in parent application
Can be run in rails engine via app namespace
![Page 27: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/27.jpg)
Other Stuff
Custom Rails Generators
Injecting routes into the parent
Config options
Initializers
etc. etc.
![Page 28: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/28.jpg)
Exstatic - Authorization
Uses a config option to call an authentication method
Setup in initializer
spec/controllers/pages_controller_spec.rb
![Page 29: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/29.jpg)
Exstatic - Generators
Used for migrations but no longer needed
You can however setup a rails_engine:install to automate setup
![Page 30: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/30.jpg)
Exstatic - Dynamic RoutesCan add routes directly into parent app
lib/exstatic/engine.rb
Can also ensure you aren’t overwriting a route that is defined by parent
lib/exstatic/validators/nonexistant_path_validator.rb
![Page 31: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/31.jpg)
Resources
http://edgeguides.rubyonrails.org/engines.html
http://keithschacht.com/creating-a-rails-3-engine-plugin-gem/
http://coding.smashingmagazine.com/2011/06/23/a-guide-to-starting-your-own-rails-engine-gem/
http://viget.com/extend/rails-engine-testing-with-rspec-capybara-and-factorygirl
![Page 32: Rails engines](https://reader033.vdocuments.net/reader033/viewer/2022061200/5474528ab4af9fc80a8b5639/html5/thumbnails/32.jpg)
Gems I “borrowed” from
Devise
https://github.com/plataformatec/devise
High Voltage
https://github.com/thoughtbot/high_voltage