agile and rails

59
Agile Rails Gregory McIntyre, March 2012

Upload: gregmcintyre

Post on 19-Jan-2015

77 views

Category:

Documents


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Agile and rails

Agile Rails

Gregory McIntyre, March 2012

Page 2: Agile and rails

My Creds

•University

•Ruby, TDD

•Tilefile Pty Ltd

•Python, ActionScript, Rails

•realestate.com.au

•Agile (ThoughtWorks)

Page 3: Agile and rails

Waterfall

Page 4: Agile and rails

#fail

•Impenetrable requirements documents

•Scary contracts

•Early is when you know the least

•Requirements tend to change

Page 5: Agile and rails

Agile Manifest’O

•Face time > processes and tools

•Working software > documentation

•Customer collaboration > contracts

•Embracing change > sticking to the plan

Page 6: Agile and rails

You Say Scrum, I Say...

•XP

•Scrum

•Crystal

•Lean

•Roll your own, just follow the ’festo

Page 7: Agile and rails
Page 8: Agile and rails

Turn, Turn, Turn

•Strategy

•Release

•Iteration

•Daily

Page 9: Agile and rails

Strategy

Page 10: Agile and rails

Strategy

•Mission statements

•Scope

•Risk

•Team building

•Priorities

•Finance

Page 11: Agile and rails

Project Inception

•Agile “strategy” process (1-5 days)

•Share vision

•Align goals

•Set realistic expectations

•Swap phone numbers

Page 12: Agile and rails

Strategy Constraints

Page 13: Agile and rails

Risk Chart

Page 14: Agile and rails

Release Planning

Page 15: Agile and rails

Build a Story Backlog

•Do some UX

•Write “stories”

•T-shirt sizing

Page 16: Agile and rails

Burn Down Chart

Page 17: Agile and rails

Kanban• Toyota invented it to

manage car production efficiently

•Not waterfall, not iterative

•Continuous, like a pipe

•Deliver something of value every day

Page 18: Agile and rails

Lumpy Bad

Page 19: Agile and rails

Smooth Good

Page 20: Agile and rails

Iterations

Page 21: Agile and rails

Feedback Loops

• 2-4 weeks is common

• Involve the customer

•Revise estimates

• Assess and improve

Page 22: Agile and rails

Planning Poker

Page 23: Agile and rails

Card Wall

Page 24: Agile and rails

Stand Ups

Page 25: Agile and rails

Pair Programming

Page 26: Agile and rails

Conversations

Page 27: Agile and rails

Noise

Page 28: Agile and rails

Mess

Page 29: Agile and rails

Paper and Pens

Page 30: Agile and rails

Test Driven Dev

Page 31: Agile and rails

Behaviour Driven Dev

Page 32: Agile and rails

Continuous Integration

Page 33: Agile and rails

Agile is...

•Technically “backward” (ahem, pragmatic)

•“Last minute”

•Noisy, demanding and confronting

•Practice practice practice

•About visibility, not due dates

Page 34: Agile and rails

Agile is...Deliver something of value every day

Page 35: Agile and rails

Ruby on Rails

Page 36: Agile and rails

Ruby: Expressive and Flexible

exit unless "restaurant".include? "aura"

5.times { print "Odelay!" }

['toast', 'cheese', 'wine'].each {|food| print food.capitalize }

class Blog has_many :postsend

Page 37: Agile and rails

Ruby DSLs

class Blog has_many :postsend

def has_many(things)

Page 38: Agile and rails

“LADIES, let’s make web apps with Ruby”

Page 39: Agile and rails

Rails is a Web Application Framework

•Handles an HTTP request

•Common practices

• Sensible defaults

• Keeps things orderly

Page 40: Agile and rails

Rapid Prototyping$ rails generate scaffold Post name:string title:string content:text invoke active_record create db/migrate/20120316050430_create_posts.rb create app/models/post.rb invoke rspec create spec/models/post_spec.rb route resources :posts invoke inherited_resources_controller create app/controllers/posts_controller.rb invoke erb create app/views/posts create app/views/posts/index.html.erb create app/views/posts/edit.html.erb create app/views/posts/show.html.erb create app/views/posts/new.html.erb create app/views/posts/_form.html.erb invoke rspec create spec/controllers/posts_controller_spec.rb create spec/views/posts/edit.html.erb_spec.rb create spec/views/posts/index.html.erb_spec.rb create spec/views/posts/new.html.erb_spec.rb create spec/views/posts/show.html.erb_spec.rb invoke helper create spec/helpers/posts_helper_spec.rb create spec/routing/posts_routing_spec.rb invoke rspec create spec/requests/posts_spec.rb invoke helper create app/helpers/posts_helper.rb invoke rspec invoke stylesheets create public/stylesheets/scaffold.css

Page 41: Agile and rails

Sensible DefaultsDavidson::Application.routes.draw do resource 'shared_cookie'end

shared_cookie POST /shared_cookie new_shared_cookie GET /shared_cookie/newedit_shared_cookie GET /shared_cookie/edit GET /shared_cookie PUT /shared_cookie DELETE /shared_cookie

<struts>

<package name = "MyPackage">

<interceptors> <!--Some set of common interceptors for a particular action--> <interceptor name = "A_I1" class = "MyA_I1"> <interceptor name = "A_I2" class = "MyA_I2"> <interceptor name = "A_I3" class = "MyA_I3"> <interceptor name = "A_I4" class = "MyA_I4">

<!--Another set of common interceptors --> <interceptor name = "B_I1" class = "MyB_I1"> <interceptor name = "B_I2" class = "MyB_I2"> <interceptor name = "B_I3" class = "MyB_I3"> <interceptor name = "B_I4" class = "MyB_I4"> </interceptors>

<interceptor-stack name = "A"> <interceptor-ref name = "A_I1"> <interceptor-ref name = "A_I2"> <interceptor-ref name = "A_I3"> <interceptor-ref name = "A_I4"> </interceptor-stack> <interceptor-stack name = "B"> <interceptor-ref name = "B_I1"> <interceptor-ref name = "B_I2"> <interceptor-ref name = "B_I3"> <interceptor-ref name = "B_I4"> </interceptor-stack>

<action name = "MyAction1"> <interceptor-ref name = "A"/> </action>

<action name = "MyAction2"> <interceptor-ref name = "B"/> </action>

</package>

</struts>

Page 42: Agile and rails

ERB versus HAML<%= form_for(@post) do |f| %>  <% if @post.errors.any? %>  <div id="errorExplanation">    <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>    <ul>    <% @post.errors.full_messages.each do |msg| %>      <li><%= msg %></li>    <% end %>    </ul>  </div>  <% end %>   <div class="field">    <%= f.label :name %>    <%= f.text_field :name %>  </div>  <div class="field">    <%= f.label :title %>    <%= f.text_field :title %>  </div>  <div class="field">    <%= f.label :content %>    <%= f.text_area :content %>  </div>  <div class="actions">    <%= f.submit %>  </div><% end %>

= form_for(@post) do |f| - if @post.errors.any? #errorExplanation %h2 = pluralize(@post.errors.count, "error") prohibited this post from being saved: %ul - @post.errors.full_messages.each do |msg| %li= msg .field = f.label :name = f.text_field :name .field = f.label :title = f.text_field :title .field = f.label :content = f.text_area :content .actions = f.submit

Page 43: Agile and rails

CSS versus SASShtml.rgba header#global nav .user-nav { background-color: rgba(0, 0, 0, 0.05);}

html.rgba header#global nav .user-nav .signin:active, html.rgba header#global nav .user-nav .signin:hover, html.rgba header#global nav .user-nav .signin:focus, html.rgba header#global nav .user-nav .signout:active, html.rgba header#global nav .user-nav .signout:hover, html.rgba header#global nav .user-nav .signout:focus { background-color: rgba(255, 255, 255, 0.5);}

html.no-rgba header#global nav .user-nav { background: url("/images/design/black-5.png");}

html.no-rgba header#global nav .user-nav .signin:active, html.no-rgba header#global nav .user-nav .signin:hover, html.no-rgba header#global nav .user-nav .signin:focus, html.no-rgba header#global nav .user-nav .signout:active, html.no-rgba header#global nav .user-nav .signout:hover, html.no-rgba header#global nav .user-nav .signout:focus { background-color: #edebe9;}

html &.rgba header#global nav .user-nav background-color: rgba(0, 0, 0, 0.05) .signin, .signout &:active, &:hover, &:focus background-color: rgba(255, 255, 255, 0.5)

&.no-rgba header#global nav .user-nav background: url("/images/design/black-5.png" .signin, .signout &:active, &:hover, &:focus background-color: #edebe9

Page 44: Agile and rails

SASS + Compass <3

.box +opacity(.5)

.box -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)" filter: alpha(opacity=50) opacity: .5

Page 45: Agile and rails

Advanced Compass

@import "my-icons/*.png".actions .new @include my-icons-sprite(new) .edit @include my-icons-sprite(edit) .save @include my-icons-sprite(save) .delete @include my-icons-sprite(delete)

.my-icons-sprite,

.actions .new,

.actions .edit,

.actions .save,

.actions .delete { background: url('/images/my-icons-s34fe0604ab.png') no-repeat; }

.actions .new { background-position: 0 -64px; }

.actions .edit { background-position: 0 -32px; }

.actions .save { background-position: 0 -96px; }

.actions .delete { background-position: 0 0; }

Page 46: Agile and rails

CoffeeScript

DI.Home = onload: -> @setupScrollable()

setupScrollable: -> $(".scrollable").scrollable( circular: true speed: 800 ).autoscroll( autoplay: true interval: 10000 ).navigator()

$ -> DI.Home.onload()

(function() { DI.Home = { onload: function() { return this.setupScrollable(); }, setupScrollable: function() { return $('.scrollable').scrollable({ circular: true, speed: 800 }).autoscroll({ autoplay: true, interval: 10000 }).navigator(); } }; $(function() { return DI.Home.onload(); });}).call(this);

Page 47: Agile and rails

Asset Management<%= javascript_include_tag "application" %>

<script src="/assets/application-908e25f4bf641868d8683022a5b62f54.js" type="text/javascript"></script>

<script src="/assets/core.js?body=1" type="text/javascript"></script><script src="/assets/projects.js?body=1" type="text/javascript"></script><script src="/assets/tickets.js?body=1" type="text/javascript"></script>

Page 48: Agile and rails

Rails Plugins

Page 49: Agile and rails

Rails Plugins•Authentication (Devise, OmniAuth, Facebook, Twitter)

•Storage (MySQL, PostgreSQL, MongoDB)

•Search (ElasticSearch, Sphinx)

•HTML (HAML, SASS, Less, Compass, Slim)

•Deployment (Capistrano, Heroku)

•Monitoring (Airbrake, NewRelic)

•Testing (RSpec, Cucumber, Capybara)

•JavaScript (jQuery, MooTools)

•...

Page 50: Agile and rails

PluginsI used to write functionality

Now I integrate functionality into solutions

Page 51: Agile and rails

RSpec for TDDrequire 'spec_helper'

describe Region do context 'with regions Sydney, North Sydney and Melbourne' do before do @sydney = Region.make(:sydney) @north_sydney = Region.make(:north_sydney) @melbourne = Region.make(:melbourne) end

describe '.find_by_postcode' do it 'should be Sydney for 2000' do gpo = Region.find_by_postcode('2000') gpo.should == @sydney end end endend

Page 52: Agile and rails

Cucumber for BDDFeature: Manage Articles In order to make a blog As an author I want to create and manage articles

Scenario: List articles Given I have articles titled Pizza, Breadsticks When I go to the list of article Then I should see "Pizza" And I should see "Breadsticks"

Scenario: Create an article Given I have no articles And I am on the list of articles When I follow "New Article" And I fill in "Title" with "Spuds" And I fill in "Content" with "Delicious potato wedges!" And I press "Create" Then I should see "New article created." And I should see "Spuds" And I should see "Delicious potato wedges!" And I should have 1 article

Page 53: Agile and rails

Steak for BDDrequire 'spec_helper'

feature 'Admin Sign In and Out', %q{ As an admin user I want to sign in and out So that I can access the admin section} do

background do AdminUser.make(:email => '[email protected]', :password => 'password') end

scenario 'Valid admin login' do visit admin_path fill_in 'Email', :with => '[email protected]' fill_in 'Password', :with => 'password' click_link 'Sign in' page.should have_content('Signed in successfully.') page.should have_css('a', :text => 'Sign out') end

scenario 'Invalid admin login' do visit admin_path fill_in 'Email', :with => '[email protected]' fill_in 'Password', :with => 'wrong password' click_link 'Sign in' page.should have_content('Invalid email or password.') page.should_not have_content('Sign out') endend

Page 54: Agile and rails

Selenium Webdriver

Page 55: Agile and rails

Deployment# config/deploy.rbset :application, 'davidson'set :repository, '[email protected]'set :deploy_to, '/home/davidson/deployment'set :scm, :gitrole :app, '192.168.1.1', '192.168.1.2'role :web, '192.168.1.101', '192.168.1.102'role :db, '192.168.1.229', :primary => true

$ cap staging deploy ...

$ cap production deploy...

Page 56: Agile and rails

Can I Learn All This?

•Come pair program with me

•Ask me for my collection of Rails ebooks

•Pick an app to write

•Ask (shyness is niiiice but...)

•Nettuts+, Lynda.com, Treehouse

Page 57: Agile and rails

Rails at Protein One

•Let’s rapidly prototype our ideas

•Let’s focus on solutions, not code

•Let’s test and monitor so we can be suave and confident

Page 58: Agile and rails

Designers and Me

•If you give me Photoshop files

•I will use Compass (and spriting)

•If you give me HTML5

•I will convert it to HAML, SASS and CoffeeScript

•(so if you wanna save me time...)

Page 59: Agile and rails

[email protected]

2013