Slide 1

Slide 1 text

Creating Mountable Engines Patrick Peak @peakpg

Slide 2

Slide 2 text

About me

Slide 3

Slide 3 text

Problem: Repeating yourself is easy

Slide 4

Slide 4 text

Duplication is the root of all evil.

Slide 5

Slide 5 text

Start with a library

Slide 6

Slide 6 text

Plugins are dead

Slide 7

Slide 7 text

Generated code makes upgrades costly

Slide 8

Slide 8 text

Engines are the solution

Slide 9

Slide 9 text

Agenda Agenda • - Why I care • - How to make one • - Things you can do • - Working with others

Slide 10

Slide 10 text

Evolving a CMS with engines Evolution of a CMS 3.0 Engines Introduced 3.1 -Mountable -Initializers -Asset Pipeline 4.0 2.3 Gems over plugins

Slide 11

Slide 11 text

What are engines? What are Engines? Responsibilities: •  Business Domain •  Selling Stuff •  Managing Users •  Blogging App #2 ?

Slide 12

Slide 12 text

Separation of concerns Separation of Concerns Selling Stuff Managing Users Blogging Business Domain App #2

Slide 13

Slide 13 text

Examples Popular engines

Slide 14

Slide 14 text

E-commerce

Slide 15

Slide 15 text

Authentication

Slide 16

Slide 16 text

Admin dashboards

Slide 17

Slide 17 text

Building an Engine

Slide 18

Slide 18 text

Creating an engine What the world needs… $ rails plugin new rubypress --mountable

Slide 19

Slide 19 text

Result: A gem with a rails app inside Gemspec Rails App

Slide 20

Slide 20 text

Add a resource Add a Resource $ rails g resource Page name path content

Slide 21

Slide 21 text

The ‘expected’ controller ‘Typical’ Controller

Slide 22

Slide 22 text

An isolated controller

Slide 23

Slide 23 text

Isolated Namespace Defining an isolated namespace

Slide 24

Slide 24 text

Routing Engines own their routes

Slide 25

Slide 25 text

Multiple buckets of controllers Application Engine #2 Engine #1

Slide 26

Slide 26 text

Engine routes Engine Routes Rails.application.routes.draw

Slide 27

Slide 27 text

Calling resources http://localhost:3000/rubypress/pages

Slide 28

Slide 28 text

Mounting the engine App Root

Slide 29

Slide 29 text

Route helpers Route Helpers <%= main_app.root_url %> # => / <%= rubypress.root_url %> # => /rubypress <%= rubypress.page_path(@page) %> # => /rubypress/pages/1

Slide 30

Slide 30 text

Getting smart about your routes

Slide 31

Slide 31 text

A view from inside the engine

Slide 32

Slide 32 text

Views inside your application

Slide 33

Slide 33 text

An engine by any other name…

Slide 34

Slide 34 text

Would be just as redundant

Slide 35

Slide 35 text

Migrations Sharing structure across projects

Slide 36

Slide 36 text

Namespaced tables Namespaced Tables

Slide 37

Slide 37 text

Out of the gem, into the project From Gem to Project $ rake rubypress:install:migrations - Copies from gem’s db/migrate into a project - Won’t overwrite existing

Slide 38

Slide 38 text

After installing 2 1 ####_create_rubypress_pages.rubypress.rb

Slide 39

Slide 39 text

Installing migrations for all engines For multiple engines $ rake railties:install:migrations

Slide 40

Slide 40 text

Configuration Provide reasonable defaults

Slide 41

Slide 41 text

http://edgeguides.rubyonrails.org/configuring.html

Slide 42

Slide 42 text

Initializers Initializers

Slide 43

Slide 43 text

Extending rails behavior

Slide 44

Slide 44 text

Using new DSL

Slide 45

Slide 45 text

Middleware stack

Slide 46

Slide 46 text

“Suggested” generators “Suggested” Generators

Slide 47

Slide 47 text

Make your engine configurable

Slide 48

Slide 48 text

Overriding default configuration

Slide 49

Slide 49 text

Be Nice Make life easy for new users

Slide 50

Slide 50 text

Write a README Write a Readme gem "rubypress" $ bundle install $ rake rubypress:install:migrations $ rake db:migrate mount Rubypress::Engine=>"/rubypress"

Slide 51

Slide 51 text

Improve installation Improve Installation gem "rubypress" $ rail g rubypress:install

Slide 52

Slide 52 text

Generators Generators

Slide 53

Slide 53 text

Asset Pipeline Packaging the view

Slide 54

Slide 54 text

Before 3.1 /public $ rake rubypress:copy_assets

Slide 55

Slide 55 text

After 3.1 Project gem "ckeditor_rails", "3.6.2.2"

Slide 56

Slide 56 text

My favorite key

Slide 57

Slide 57 text

Working Together Ups and downs of multiple engines

Slide 58

Slide 58 text

Common stacks are easier My Site BrowerCMS News Blog

Slide 59

Slide 59 text

Allows for established conventions Establishing Conventions $ rails g cms:install bcms_news

Slide 60

Slide 60 text

A common installer

Slide 61

Slide 61 text

The Holy Grail for engine ecosystem The vision Your Engine Rails Admin

Slide 62

Slide 62 text

Challenges on our quest Challenges A. Incompatible dependencies B. Rails has no common security model C. Mismatched user interfaces

Slide 63

Slide 63 text

A. Incompatible dependencies Devise =2.1.1 ~>2.0.0 Rails Admin

Slide 64

Slide 64 text

Managing your engine dependencies Solving Dependencies - Minimize dependencies - Be Rational: Major.Minor.Build (i.e. 3.5.4) - Major – Backwards incompatible - Minor – New features - Build – Details - Robustness Principle: - Be liberal in what you accept - ~> 2.0 better than ~>2.0.0

Slide 65

Slide 65 text

B. No common security model Your App Restful Auth Devise current_user?

Slide 66

Slide 66 text

Authentication Who are you, really?

Slide 67

Slide 67 text

Authorization Are you allowed to do that?

Slide 68

Slide 68 text

I don’t care which, just pick one…

Slide 69

Slide 69 text

C. Mismatched UIs

Slide 70

Slide 70 text

Recap What I hope you learned

Slide 71

Slide 71 text

Engines are the future, and awesome.

Slide 72

Slide 72 text

Reduce errors from duplication

Slide 73

Slide 73 text

When done right…

Slide 74

Slide 74 text

The End Thanks!

Slide 75

Slide 75 text

Attributions http://dilbert.com/strips/comic/2009-12-03/ http://trevorlibrarian.wordpress.com/2012/04/04/safety-first/ http://www.flickr.com/photos/jowo/95371566/sizes/o/in/photostream/ http://www.flickr.com/photos/rosenfeldmedia/4459977458/sizes/o/in/photostream/ https://www.ruby-toolbox.com/ http://www.flickr.com/photos/7571290@N05/440978769/sizes/m/in/photostream/ http://www.spreecommerce.com http://www.flickr.com/photos/verseguru/168920451/sizes/o/in/photostream/ http://www.flickr.com/photos/richardgiles/5284155911/sizes/o/in/photostream/ http://www.flickr.com/photos/museemccordmuseum/2918567169/sizes/o/in/photostream/ http://www.flickr.com/photos/whisperwolf/4487007569/

Slide 76

Slide 76 text

Questions?