nedap rails workshop

193
Ruby on Rails

Upload: andre-foeken

Post on 06-May-2015

1.515 views

Category:

Entertainment & Humor


3 download

TRANSCRIPT

Page 1: Nedap Rails Workshop

Ruby on Rails

Page 2: Nedap Rails Workshop

Hellow

Bart André Dirkjan

Page 3: Nedap Rails Workshop

Hellow

Bart André Dirkjan

Page 4: Nedap Rails Workshop
Page 5: Nedap Rails Workshop

Laptops, apple

Page 6: Nedap Rails Workshop

Development is more than coding

Page 7: Nedap Rails Workshop
Page 8: Nedap Rails Workshop
Page 9: Nedap Rails Workshop
Page 10: Nedap Rails Workshop

Ruby on Rails

Page 11: Nedap Rails Workshop

Ruby on Rails

Page 12: Nedap Rails Workshop

Ruby on Rails

Language

Page 13: Nedap Rails Workshop

Ruby on Rails

Language

Framework

Page 14: Nedap Rails Workshop

What are we doing today?

1

2

3

Ruby basics

Rails terminology / vision

Build something simple

Page 15: Nedap Rails Workshop

What are we doing today?

1

2

3

Ruby basics

Rails terminology / vision

Build something simple

But first....

Page 16: Nedap Rails Workshop

Very simple example

Page 17: Nedap Rails Workshop

Address Book■ Generate a new Rails Application

■ Generate some stuff

■ Prepare the database

■ Start the application

■ View application and be excited!

Page 18: Nedap Rails Workshop
Page 19: Nedap Rails Workshop
Page 20: Nedap Rails Workshop

Terminal

Page 21: Nedap Rails Workshop

Terminal$ rails address_book

create create app/controllers create app/helpers create app/models create app/views/layouts create test/functional create test/integration

... create log/server.log create log/production.log create log/development.log create log/test.log

Page 22: Nedap Rails Workshop

Terminal$ rails address_book

create create app/controllers create app/helpers create app/models create app/views/layouts create test/functional create test/integration

... create log/server.log create log/production.log create log/development.log create log/test.log

$ cd address_book

Page 23: Nedap Rails Workshop

Terminal

Page 24: Nedap Rails Workshop

Terminal$ ./script/generate scaffold person name:stringexists app/controllers/

exists app/helpers/ create app/views/people

...

Page 25: Nedap Rails Workshop

Terminal$ ./script/generate scaffold person name:stringexists app/controllers/

exists app/helpers/ create app/views/people

...

./script/destroy to undo

Page 26: Nedap Rails Workshop

Terminal

Page 27: Nedap Rails Workshop

Terminal$ rake db:migrate

== 00000000000000 CreatePeople: migrating =============-- create_table(:people) -> 0.0177s== 00000000000000 CreatePeople: migrated (0.0180s) ====

Page 28: Nedap Rails Workshop

Terminal$ rake db:migrate

== 00000000000000 CreatePeople: migrating =============-- create_table(:people) -> 0.0177s== 00000000000000 CreatePeople: migrated (0.0180s) ====

rake db:rollback to undo

Page 29: Nedap Rails Workshop

⌘ N

Page 30: Nedap Rails Workshop

Terminal

Page 31: Nedap Rails Workshop

Terminal

$ cd address_book

Page 32: Nedap Rails Workshop

Terminal

$ ./script/server=> Booting Mongrel => Rails 2.1.0 application starting on http://0.0.0.0:3000=> Call with -d to detach=> Ctrl-C to shutdown server** Starting Mongrel listening at 0.0.0.0:3000** Starting Rails with development environment...** Rails loaded.** Loading any Rails specific GemPlugins** Signals ready. TERM => stop. USR2 => restart. ** Rails signals registered. ** Mongrel 1.1.4 available at 0.0.0.0:3000** Use CTRL-C to stop.

$ cd address_book

Page 33: Nedap Rails Workshop
Page 35: Nedap Rails Workshop
Page 36: Nedap Rails Workshop

http://localhost:3000/people

Page 37: Nedap Rails Workshop
Page 38: Nedap Rails Workshop
Page 39: Nedap Rails Workshop
Page 40: Nedap Rails Workshop
Page 41: Nedap Rails Workshop
Page 42: Nedap Rails Workshop

It all seems like magic...

Page 43: Nedap Rails Workshop

You feel lost...

Page 44: Nedap Rails Workshop

This is normal. It will pass.

Page 45: Nedap Rails Workshop

Close all

Page 46: Nedap Rails Workshop

Ruby

Page 47: Nedap Rails Workshop

The basics■ Objects

■ Variables

■ Methods

■ Inheritance & Modules

■ Blocks

Page 48: Nedap Rails Workshop

Objects, variables & methods

Page 49: Nedap Rails Workshop

Objects, variables & methods

class Person attr_accessor :name def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

Page 50: Nedap Rails Workshop

Objects, variables & methods

class Person attr_accessor :name def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class name

Page 51: Nedap Rails Workshop

Objects, variables & methods

class Person attr_accessor :name def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class nameinstance variable

Page 52: Nedap Rails Workshop

Objects, variables & methods

class Person attr_accessor :name def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class nameinstance variable

method

Page 53: Nedap Rails Workshop

class Person attr_accessor :name def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

Console: using a class

Page 54: Nedap Rails Workshop

class Person attr_accessor :name def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

Console: using a class

>> andre = Person.new

>> andre.name = ‘Andre’

Page 55: Nedap Rails Workshop

class Person attr_accessor :name def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

Console: using a class

>> bart = Person.new

>> bart.name = ‘Bart’

>> andre = Person.new

>> andre.name = ‘Andre’

Page 56: Nedap Rails Workshop

class Person attr_accessor :name def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

Console: using a class

“Bart thinks Andre is a stupid dog!”

>> bart = Person.new

>> bart.name = ‘Bart’

>> andre = Person.new

>> andre.name = ‘Andre’

>> bart.insults(andre, “dog”)

Page 57: Nedap Rails Workshop

Inheritance

class Student < Person def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name end

Page 58: Nedap Rails Workshop

Inheritance

class Student < Person def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

Student inherits from personclass Person

attr_accessor :name end

Page 59: Nedap Rails Workshop

Modules

Page 60: Nedap Rails Workshop

Woman Man

Person

Page 61: Nedap Rails Workshop

Woman Man

Person

Driving skill

Page 62: Nedap Rails Workshop

Woman Man

PersonDriving skill

Page 63: Nedap Rails Workshop

Woman Man

Person

Driving skill

Page 64: Nedap Rails Workshop

Andre Bart

Woman Man

Person

Driving skill

Page 65: Nedap Rails Workshop

Modulesmodule Insulting def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name include Insulting end

Page 66: Nedap Rails Workshop

Modulesmodule Insulting def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name include Insulting end

Creates an ‘Insulting’ module

Page 67: Nedap Rails Workshop

Modulesmodule Insulting def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name include Insulting end

Creates an ‘Insulting’ module

Person classes can

‘Insult’

Page 68: Nedap Rails Workshop

Modulesmodule Insulting def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name include Insulting end

Creates an ‘Insulting’ module

Person classes can

‘Insult’ class Robot

attr_accessor :name include Insulting

end

Everyone can insult now!

Page 69: Nedap Rails Workshop

Console: extending on the fly

module Insulting def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name end

Page 70: Nedap Rails Workshop

Console: extending on the fly

>> andre = Person.new

>> andre.name = “Andre”

>> andre.extend(Insulting)

module Insulting def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name end

nil

Page 71: Nedap Rails Workshop

Console: extending on the fly

>> andre = Person.new

>> andre.name = “Andre”

>> andre.extend(Insulting)

module Insulting def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name end

nil

“Andre thinks Bart is a stupid cow!”

>> andre.insults(bart)

Page 72: Nedap Rails Workshop

Console: extending on the fly

>> andre = Person.new

>> andre.name = “Andre”

>> andre.extend(Insulting)

module Insulting def insults(other, object="cow") "#{name} thinks #{other.name} is a stupid #{object}!" end end

class Person attr_accessor :name end

nil

“Andre thinks Bart is a stupid cow!”

>> andre.insults(bart)

We could also extend an entire class like this!

Page 73: Nedap Rails Workshop

Man

Driving skill

Insulting

Gardening

Person

Page 74: Nedap Rails Workshop

Man

Driving skill

Insulting

Gardening

Person

How do we test if this man can insult?

Page 75: Nedap Rails Workshop

Duck-typing

Page 76: Nedap Rails Workshop

— Lisa Graves

If it walks like a duck and quacks like a duck, it's a duck.

Page 77: Nedap Rails Workshop

andre.respond_to?(:insult)

Page 78: Nedap Rails Workshop

Woman Man

Person

Page 79: Nedap Rails Workshop

DriverWoman Man

Person

Page 80: Nedap Rails Workshop

Woman Man

Person

Driving skill

Page 81: Nedap Rails Workshop

Blocks

Page 82: Nedap Rails Workshop

Console: using blocks

class Person attr_accessor :name end

Page 83: Nedap Rails Workshop

Console: using blocks

>> people

class Person attr_accessor :name end

[<#Person:0x00 @name=”Andre”>,<#Person:0x00 @name=”Bart”>]

Page 84: Nedap Rails Workshop

Console: using blocks

>> people

class Person attr_accessor :name end

[<#Person:0x00 @name=”Andre”>,<#Person:0x00 @name=”Bart”>]

>> people.map{ |item| “#{item.name} is kewl” }[“Andre is kewl”, “Bart is kewl”]

Page 85: Nedap Rails Workshop

Console: using blocks

>> people

class Person attr_accessor :name end

[<#Person:0x00 @name=”Andre”>,<#Person:0x00 @name=”Bart”>]

>> people.map{ |item| “#{item.name} is kewl” }[“Andre is kewl”, “Bart is kewl”]

We also have: select, reject and inject to work with collections!

Page 86: Nedap Rails Workshop

You know Ruby!

Page 87: Nedap Rails Workshop

You know Ruby! Sorta...

Page 88: Nedap Rails Workshop

You know Ruby! Sorta...

Page 89: Nedap Rails Workshop

PART II

Page 90: Nedap Rails Workshop

Convention over configuration

Page 91: Nedap Rails Workshop

railsenvy.com

Page 92: Nedap Rails Workshop

M V CMODEL

VIEW

CONTROLLER

Page 93: Nedap Rails Workshop

Models

Views

Controllers

Talk to the database, contain business logic

Show the content to the user

Provide the glue, prepare data when needed

Page 94: Nedap Rails Workshop

— Tyler Durden, Fight Club

You are not a beautiful and unique snowflake. You are the same decaying organic matter as everyone else, and we are all a part of the same compost pile.

Page 95: Nedap Rails Workshop

RESOURCE

SEE CHANGE

REMOVEADD

Page 96: Nedap Rails Workshop

RESOURCE

SEE CHANGE

REMOVEADD

Show me something

Page 97: Nedap Rails Workshop

RESOURCE

SEE CHANGE

REMOVEADD

Show me something

Add someone

Page 98: Nedap Rails Workshop

RESOURCE

SEE CHANGE

REMOVEADD

Show me something

Add someone

Change something

Page 99: Nedap Rails Workshop

RESOURCE

SEE CHANGE

REMOVEADD

Show me something

Add someone

Change something

Delete stuff

Page 100: Nedap Rails Workshop

C R U DCREATE

DELETE

UPDATE

READ

Page 101: Nedap Rails Workshop

C R U DCREATE

DELETE

UPDATE

READ

Page 102: Nedap Rails Workshop

C R U DHTTP!

CREATE

DELETE

UPDATE

READ

Page 103: Nedap Rails Workshop

C R U DPOST

HTTP!

CREATE

DELETE

UPDATE

READ

Page 104: Nedap Rails Workshop

C R U DPOST

GET

HTTP!

CREATE

DELETE

UPDATE

READ

Page 105: Nedap Rails Workshop

C R U DPOST PUT

GET

HTTP!

CREATE

DELETE

UPDATE

READ

Page 106: Nedap Rails Workshop

C R U DPOST

DELETE

PUT

GET

HTTP!

CREATE

DELETE

UPDATE

READ

Page 107: Nedap Rails Workshop

http://www.snowflake.org/people/1

Page 108: Nedap Rails Workshop

U R IUNIVERSAL

RESOURCE

IDENTIFIER

Page 109: Nedap Rails Workshop
Page 110: Nedap Rails Workshop

/people POSTADD

Page 111: Nedap Rails Workshop

/people

/people

POSTGET

ADDSEE

Page 112: Nedap Rails Workshop

/people

/people

/people/1

POSTGETPUT

ADDSEECHANGE

Page 113: Nedap Rails Workshop

/people

/people

/people/1

/people/1

POSTGETPUTDELETE

ADDSEECHANGEREMOVE

Page 114: Nedap Rails Workshop

R E S TREPRESENTATIONAL STATE TRANSFER

Page 115: Nedap Rails Workshop

RAILS CONTROLLER ACTIONS

Page 116: Nedap Rails Workshop

INDEX NEW EDIT

SHOW

RAILS CONTROLLER ACTIONS

CREATE UPDATE

DESTROY

Page 117: Nedap Rails Workshop

Building something...

Page 118: Nedap Rails Workshop

Let’s get started

Page 119: Nedap Rails Workshop

Choose a subject

Page 120: Nedap Rails Workshop

2 hrsIT WON’T BE ENOUGH...

Page 121: Nedap Rails Workshop
Page 122: Nedap Rails Workshop

■ You should have an idea

■ You should have a rough sketch

■ You should have thought of what models you need

■ You should think of their relation to each other

■ Pick an pair of models with a 1..* relationship

First 15 minutes

BeerStudent1 *

Page 123: Nedap Rails Workshop

Next 10 minutes■ You should have a new rails app

$ rails [your_app_name]

■ You should have generated the models$ ./script/generate scaffold [model_name] [attr]:[type

type = string, text, integer, float, boolean, date, time, datetime

reserved attrs => type, version

Page 124: Nedap Rails Workshop

mate .

Page 125: Nedap Rails Workshop
Page 126: Nedap Rails Workshop
Page 127: Nedap Rails Workshop
Page 128: Nedap Rails Workshop

App structure- app

- models

- views

- controllers

- config

- db

- migrate

Page 129: Nedap Rails Workshop

App structure- app

- models

- views

- controllers

- config

- db

- migrate

the model files

Page 130: Nedap Rails Workshop

App structure- app

- models

- views

- controllers

- config

- db

- migrate

the model files

templates for HTML

Page 131: Nedap Rails Workshop

App structure- app

- models

- views

- controllers

- config

- db

- migrate

the model files

templates for HTML

the controller files

Page 132: Nedap Rails Workshop

App structure- app

- models

- views

- controllers

- config

- db

- migrate

the model files

templates for HTML

the controller files

basic configuration

Page 133: Nedap Rails Workshop

App structure- app

- models

- views

- controllers

- config

- db

- migrate

the model files

templates for HTML

the controller files

basic configuration

database migrations

Page 134: Nedap Rails Workshop

Migrations

Page 135: Nedap Rails Workshop

db/migrate/00000000_create_people.rbclass CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name

t.timestamps end end

def self.down drop_table :people endend

Page 136: Nedap Rails Workshop

db/migrate/00000000_create_people.rbclass CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name

t.timestamps end end

def self.down drop_table :people endend

Create a ‘People’ table on UP

Page 137: Nedap Rails Workshop

db/migrate/00000000_create_people.rbclass CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name

t.timestamps end end

def self.down drop_table :people endend

Create a ‘People’ table on UPWith a ‘Name’

String

Page 138: Nedap Rails Workshop

db/migrate/00000000_create_people.rbclass CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name

t.timestamps end end

def self.down drop_table :people endend

Create a ‘People’ table on UPWith a ‘Name’

String

And some time-stamps: created_at & updated_at

Page 139: Nedap Rails Workshop

db/migrate/00000000_create_people.rbclass CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name

t.timestamps end end

def self.down drop_table :people endend

Create a ‘People’ table on UPWith a ‘Name’

String

And some time-stamps: created_at & updated_at

Drop the table on DOWN

Page 140: Nedap Rails Workshop

Relationships

Page 141: Nedap Rails Workshop

BeerStudent1 *

app/models/student.rbclass Student < ActiveRecord::Base has_many :beers end

app/models/beer.rbclass Beer < ActiveRecord::Base belongs_to :student end

Page 142: Nedap Rails Workshop

db/migrate/00000000_create_beers.rbclass CreateBeers < ActiveRecord::Migration def self.up create_table :beers do |t| t.string :brand t.references :student t.timestamps end end

def self.down drop_table :beers endend

Page 143: Nedap Rails Workshop

db/migrate/00000000_create_beers.rbclass CreateBeers < ActiveRecord::Migration def self.up create_table :beers do |t| t.string :brand t.references :student t.timestamps end end

def self.down drop_table :beers endend

Add a reference to Student(:student_id)

Page 144: Nedap Rails Workshop

Next 10 minutes■ You should update your model files when needed

belongs_to, has_many, has_one, has_many :through

■ You should add references to migrationst.references :student

Page 145: Nedap Rails Workshop

Next 5 minutes■ You should have migrated the database

$ rake db:migrate

■ You should have a running server$ ./script/server

■ You should see your app$ open http://localhost:3000

Page 146: Nedap Rails Workshop

Routes

Page 147: Nedap Rails Workshop

config/routes.rb

ActionController::Routing::Routes.draw do |map| map.resources :students map.resources :beers

# You can have the root of your site routed with map.root # map.root :controller => "welcome"

map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format'end

Page 148: Nedap Rails Workshop

config/routes.rb

ActionController::Routing::Routes.draw do |map| map.resources :students map.resources :beers

# You can have the root of your site routed with map.root # map.root :controller => "welcome"

map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format'end

Routes for each resource

Page 149: Nedap Rails Workshop

config/routes.rb

ActionController::Routing::Routes.draw do |map| map.resources :students map.resources :beers

# You can have the root of your site routed with map.root # map.root :controller => "welcome"

map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format'end

Routes for each resource

Remove # and change :controller to ‘students’

Page 150: Nedap Rails Workshop

/people

/people

/people/1

/people/1

POSTGETPUTDELETE

ADDSEECHANGEREMOVE

/people/1

/people/1/edit

/people/new

GETGETGET

SEECHANGEADD

Page 151: Nedap Rails Workshop

Next 5 minutes■ Change the routes

Uncomment & choose default controller

■ Remove ‘public/index.html’$ rm public/index.html

■ Refresh your browser

Page 152: Nedap Rails Workshop

ActiveRecord

Page 153: Nedap Rails Workshop

One class per table

One instance per row

Page 154: Nedap Rails Workshop

One class per table

One instance per rowColumns are attributes

Page 155: Nedap Rails Workshop

Student.find_by_name(“Andre”)

Student.find(:first, :conditions => [“name = ?”,”Andre”])

Page 156: Nedap Rails Workshop

Student.find_all_by_name(“Andre”)

Student.find(:all, :conditions => [“name = ?”,”Andre”])

Page 157: Nedap Rails Workshop

andre = Student.new( :name => “Andre” )

andre.save

Page 158: Nedap Rails Workshop

Next 10 minutes■ You should play with your app, create some instances

We created a student named “Andre”

■ You should start a console$ ./script/console

■ You should build a few relationships using the console>> andre = Student.find_by_name(“Andre”)

>> beer = andre.beers.create( :brand => “Grolsch” )

>> beer.student.name ”Andre”

Page 159: Nedap Rails Workshop

Views

Page 160: Nedap Rails Workshop

app/views/beer/new.html.erb

<h1>New beer</h1>

<% form_for(@beer) do |f| %> <%= f.error_messages %>

<p> <%= f.label :brand %><br /> <%= f.text_field :brand %> </p> <p> <%= f.submit "Create" %> </p><% end %>

<%= link_to 'Back', beers_path %>

Page 161: Nedap Rails Workshop

app/views/beer/new.html.erb

<h1>New beer</h1>

<% form_for(@beer) do |f| %> <%= f.error_messages %>

<p> <%= f.label :brand %><br /> <%= f.text_field :brand %> </p> <p> <%= f.submit "Create" %> </p><% end %>

<%= link_to 'Back', beers_path %>

Title of the page

Page 162: Nedap Rails Workshop

app/views/beer/new.html.erb

<h1>New beer</h1>

<% form_for(@beer) do |f| %> <%= f.error_messages %>

<p> <%= f.label :brand %><br /> <%= f.text_field :brand %> </p> <p> <%= f.submit "Create" %> </p><% end %>

<%= link_to 'Back', beers_path %>

Title of the pageA form

Page 163: Nedap Rails Workshop

app/views/beer/new.html.erb

<h1>New beer</h1>

<% form_for(@beer) do |f| %> <%= f.error_messages %>

<p> <%= f.label :brand %><br /> <%= f.text_field :brand %> </p> <p> <%= f.submit "Create" %> </p><% end %>

<%= link_to 'Back', beers_path %>

Title of the pageA form

Show errors messages if something goes wrong

Page 164: Nedap Rails Workshop

app/views/beer/new.html.erb

<h1>New beer</h1>

<% form_for(@beer) do |f| %> <%= f.error_messages %>

<p> <%= f.label :brand %><br /> <%= f.text_field :brand %> </p> <p> <%= f.submit "Create" %> </p><% end %>

<%= link_to 'Back', beers_path %>

Title of the pageA form

Show errors messages if something goes wrong

Some fields and a button

Page 165: Nedap Rails Workshop

app/views/beer/new.html.erb

<h1>New beer</h1>

<% form_for(@beer) do |f| %> <%= f.error_messages %>

<p> <%= f.label :brand %><br /> <%= f.text_field :brand %> </p> <p> <%= f.submit "Create" %> </p><% end %>

<%= link_to 'Back', beers_path %>

Title of the pageA form

Show errors messages if something goes wrong

Some fields and a button

Back link

Page 166: Nedap Rails Workshop

app/views/beer/new.html.erb

<h1>New beer</h1>

<% form_for(@beer) do |f| %> <%= f.error_messages %>

<p> <%= f.label :brand %><br /> <%= f.text_field :brand %> </p> <p> <%= f.submit "Create" %> </p><% end %>

<%= link_to 'Back', beers_path %>

Page 167: Nedap Rails Workshop

app/views/beer/new.html.erb<h1>New beer</h1>

<% form_for(@beer) do |f| %> <%= f.error_messages %>

<p> <%= f.label :brand %><br /> <%= f.text_field :brand %> </p>

<p> <%= f.label :student %><br /> <%= f.collection_select :student_id, Student.find(:all), :id, :name %> </p>

<p> <%= f.submit "Create" %> </p><% end %>

<%= link_to 'Back', beers_path %>

Page 168: Nedap Rails Workshop

Next 15 minutes■ Should be able to set a belongs_to relationship

collection_select

■ Relationship must be able to be set on new and existing objectsChange both the edit and new view!

■ Test that it really works!

Try to edit the show view to represent the object relationship so another human understands it!

Page 169: Nedap Rails Workshop

ValidationsThis is a behaviour...

Page 170: Nedap Rails Workshop

ValidationsThis is a behaviour...

Page 171: Nedap Rails Workshop

B D DBEHAVIOUR DRIVEN DEVELOPMENT

Page 172: Nedap Rails Workshop

How should a student behave?

Page 173: Nedap Rails Workshop

Student■ should never have a blank name

Page 174: Nedap Rails Workshop

Terminal

Page 175: Nedap Rails Workshop

Terminal$ ./script/generate rspec create lib/tasks/rspec.rake

create script/autospec create script/spec create script/spec_server create spec create spec/rcov.opts create spec/spec.opts create spec/spec_helper.rb create stories create stories/all.rb create stories/helper.rb

Page 176: Nedap Rails Workshop

Terminal$ ./script/generate rspec create lib/tasks/rspec.rake

create script/autospec create script/spec create script/spec_server create spec create spec/rcov.opts create spec/spec.opts create spec/spec_helper.rb create stories create stories/all.rb create stories/helper.rb

$ ./script/generate rspec_model student

Page 177: Nedap Rails Workshop

Terminal$ ./script/generate rspec create lib/tasks/rspec.rake

create script/autospec create script/spec create script/spec_server create spec create spec/rcov.opts create spec/spec.opts create spec/spec_helper.rb create stories create stories/all.rb create stories/helper.rb

$ ./script/generate rspec_model student

$ rake db:migrate RAILS_ENV=test

Page 178: Nedap Rails Workshop

spec/models/student_spec.rbrequire File.dirname(__FILE__) + '/../spec_helper'

describe Student do it "should never have a blank name" do

no_name = Student.new( :name => “” ) no_name.should_not be_valid

end end

Page 179: Nedap Rails Workshop

spec/models/student_spec.rbrequire File.dirname(__FILE__) + '/../spec_helper'

describe Student do it "should never have a blank name" do

no_name = Student.new( :name => “” ) no_name.should_not be_valid

end end

ActiveRecord objects have a valid? method

Page 180: Nedap Rails Workshop

Terminal: Running tests

require File.dirname(__FILE__) + '/../spec_helper'

describe Student do it "should never have a blank name" do

no_name = Student.new( :name => “” ) no_name.should_not be_valid

end end

Page 181: Nedap Rails Workshop

Terminal: Running tests

$ ruby spec/models/student_spec.rb F

Failed:Student should never have a blank name (FAILED)

Finished in 0.1 seconds

1 examples, 1 failures, 0 pending

require File.dirname(__FILE__) + '/../spec_helper'

describe Student do it "should never have a blank name" do

no_name = Student.new( :name => “” ) no_name.should_not be_valid

end end

Page 182: Nedap Rails Workshop

app/models/student.rbclass Student < ActiveRecord::Base has_many :beers validates_presence_of :name end

Page 183: Nedap Rails Workshop

app/models/student.rbclass Student < ActiveRecord::Base has_many :beers validates_presence_of :name end

Page 184: Nedap Rails Workshop

Next 5 minutes■ Add Rspec to your project

./script/generate rspec

■ Generate specs for your models - don’t replace files!./script/generate rspec_model [model-name]

■ Clean spec files. Make sure they look like this.

■ Build the test databaserake db:migrate RAILS_ENV=test

require File.dirname(__FILE__) + '/../spec_helper'

describe Student do end

Page 185: Nedap Rails Workshop

Next 15 minutes■ Spec out all your validations

■ First, all your specs should fail

■ Add the validations to your modelsvalidates_presence_ofvalidates_uniqueness_ofvalidates_format_ofvalidates_length_ofvalidates_numericality_of

■ Then, all your specs should pass

Page 186: Nedap Rails Workshop

Connecting dots

Page 187: Nedap Rails Workshop

Connecting dots.............

Page 188: Nedap Rails Workshop

Let’s make our view a little bit more fun

Page 189: Nedap Rails Workshop

<p> <b>Name:</b> <%=h @student.name %></p>

<%= link_to 'Edit', edit_person_path(@person) %> |<%= link_to 'Back', people_path %>

app/views/students/show.html.erb

Page 190: Nedap Rails Workshop

app/views/students/show.html.erb<p> <b>Name:</b> <%=h @student.name %></p>

<ul><% @student.beers.each do |beer| %> <li> 1 x <%= h beer.brand %> </li><% end %></ul>

<%= link_to 'Edit', edit_person_path(@person) %> |<%= link_to 'Back', people_path %>

Page 191: Nedap Rails Workshop

Next 10 minutes■ Pimp one of your views!

Page 192: Nedap Rails Workshop

You all get a PDF version of this book to continue working on your project,

thanks to pragprog.com

FREE!

Page 193: Nedap Rails Workshop

</PRESENTATION>