Nedap Rails Workshop

  • 1,452 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,452
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
45
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Ruby on Rails
  • 2. Hellow Bart André Dirkjan
  • 3. Hellow Bart André Dirkjan
  • 4. Laptops, apple
  • 5. Development is more than coding
  • 6. Ruby on Rails
  • 7. Ruby on Rails
  • 8. Language Ruby on Rails
  • 9. Language Ruby on Rails Framework
  • 10. What are we doing today? 1 Ruby basics 2 Rails terminology / vision 3 Build something simple
  • 11. What are we doing today? 1 Ruby basics st .... ut fir B 2 Rails terminology / vision 3 Build something simple
  • 12. Very simple example
  • 13. Address Book ■ Generate a new Rails Application ■ Generate some stuff ■ Prepare the database ■ Start the application ■ View application and be excited!
  • 14. Terminal
  • 15. 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
  • 16. 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
  • 17. Terminal
  • 18. Terminal $ ./script/generate scaffold person name:string exists app/controllers/ exists app/helpers/ create app/views/people ...
  • 19. ./script/destroy to undo Terminal $ ./script/generate scaffold person name:string exists app/controllers/ exists app/helpers/ create app/views/people ...
  • 20. Terminal
  • 21. Terminal $ rake db:migrate == 00000000000000 CreatePeople: migrating ============= -- create_table(:people) -> 0.0177s == 00000000000000 CreatePeople: migrated (0.0180s) ====
  • 22. rake db:rollback to undo Terminal $ rake db:migrate == 00000000000000 CreatePeople: migrating ============= -- create_table(:people) -> 0.0177s == 00000000000000 CreatePeople: migrated (0.0180s) ====
  • 23. ⌘N
  • 24. Terminal
  • 25. Terminal $ cd address_book
  • 26. Terminal $ cd address_book $ ./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.
  • 27. http://localhost:3000/
  • 28. http://localhost:3000/people
  • 29. It all seems like magic...
  • 30. You feel lost...
  • 31. This is normal. It will pass.
  • 32. Close all
  • 33. Ruby
  • 34. The basics ■ Objects ■ Variables ■ Methods ■ Inheritance & Modules ■ Blocks
  • 35. Objects, variables & methods
  • 36. Objects, variables & methods class Person attr_accessor :name def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end
  • 37. class name Objects, variables & methods class Person attr_accessor :name def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end
  • 38. class name Objects, variables & methods instance variable class Person attr_accessor :name def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end
  • 39. class name Objects, variables & methods instance variable class Person method attr_accessor :name def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end
  • 40. class Person attr_accessor :name def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end Console: using a class
  • 41. class Person attr_accessor :name def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end Console: using a class >> andre = Person.new >> andre.name = ‘Andre’
  • 42. class Person attr_accessor :name def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end Console: using a class >> andre = Person.new >> andre.name = ‘Andre’ >> bart = Person.new >> bart.name = ‘Bart’
  • 43. class Person attr_accessor :name def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end Console: using a class >> andre = Person.new >> andre.name = ‘Andre’ >> bart = Person.new >> bart.name = ‘Bart’ >> bart.insults(andre, “dog”) “Bart thinks Andre is a stupid dog!”
  • 44. Inheritance class Person attr_accessor :name end class Student < Person def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end
  • 45. Inheritance Student inherits class Person attr_accessor :name from person end class Student < Person def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end
  • 46. Modules
  • 47. Person Woman Man
  • 48. Driving skill Person Woman Man
  • 49. Driving skill Person Woman Man
  • 50. Person Driving skill Woman Man
  • 51. Person Woman Man Driving skill Andre Bart
  • 52. Modules module Insulting def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end class Person attr_accessor :name include Insulting end
  • 53. Creates an Modules ‘Insulting’ module module Insulting def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end class Person attr_accessor :name include Insulting end
  • 54. Creates an Modules ‘Insulting’ module module Insulting def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end Person end classes can class Person ‘Insult’ attr_accessor :name include Insulting end
  • 55. Creates an Modules ‘Insulting’ module module Insulting def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end Person end classes can class Person class Robot ‘Insult’ attr_accessor :name attr_accessor :name include Insulting include Insulting end end Everyone can insult now!
  • 56. module Insulting def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end class Person attr_accessor :name end Console: extending on the fly
  • 57. module Insulting def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end class Person attr_accessor :name end Console: extending on the fly >> andre = Person.new >> andre.name = “Andre” >> andre.extend(Insulting) nil
  • 58. module Insulting def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end class Person attr_accessor :name end Console: extending on the fly >> andre = Person.new >> andre.name = “Andre” >> andre.extend(Insulting) nil >> andre.insults(bart) “Andre thinks Bart is a stupid cow!”
  • 59. module Insulting def insults(other, object=quot;cowquot;) quot;#{name} thinks #{other.name} is a stupid #{object}!quot; end end class Person attr_accessor :name end Console: extending on the flyWe could also extend an entire class like this! >> andre = Person.new >> andre.name = “Andre” >> andre.extend(Insulting) nil >> andre.insults(bart) “Andre thinks Bart is a stupid cow!”
  • 60. Man Person Driving skill Insulting Gardening
  • 61. Man Person Driving skill Insulting Gardening How do we test if this man can insult?
  • 62. Duck-typing
  • 63. If it walks like a duck and quacks like a duck, it's a duck. — Lisa Graves
  • 64. andre.respond_to?(:insult)
  • 65. Person Woman Man
  • 66. Person Woman Man Driver
  • 67. Person Driving skill Woman Man
  • 68. Blocks
  • 69. class Person attr_accessor :name end Console: using blocks
  • 70. class Person attr_accessor :name end Console: using blocks >> people [<#Person:0x00 @name=”Andre”>,<#Person:0x00 @name=”Bart”>]
  • 71. class Person attr_accessor :name end Console: using blocks >> people [<#Person:0x00 @name=”Andre”>,<#Person:0x00 @name=”Bart”>] >> people.map{ |item| “#{item.name} is kewl” } [“Andre is kewl”, “Bart is kewl”]
  • 72. class Person attr_accessor :name end Console: using blocks also have: select, reject and inject to We work with collections! >> people [<#Person:0x00 @name=”Andre”>,<#Person:0x00 @name=”Bart”>] >> people.map{ |item| “#{item.name} is kewl” } [“Andre is kewl”, “Bart is kewl”]
  • 73. You know Ruby!
  • 74. You know Ruby! Sorta...
  • 75. You know Ruby! Sorta...
  • 76. PART II
  • 77. Convention over configuration
  • 78. railsenvy.com
  • 79. VIEW MVC MODEL CONTROLLER
  • 80. Models Talk to the database, contain business logic Controllers Provide the glue, prepare data when needed Views Show the content to the user
  • 81. 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. — Tyler Durden, Fight Club
  • 82. SEE CHANGE RESOURCE ADD REMOVE
  • 83. Show me something SEE CHANGE RESOURCE ADD REMOVE
  • 84. Show me something SEE CHANGE RESOURCE Add someone ADD REMOVE
  • 85. Show me something SEE CHANGE Change something RESOURCE Add someone ADD REMOVE
  • 86. Show me something SEE CHANGE Change something RESOURCE Add someone Delete stuff ADD REMOVE
  • 87. CREATE UPDATE CRUD READ DELETE
  • 88. CREATE UPDATE CRUD READ DELETE
  • 89. CREATE UPDATE CRUD READ DELETE HTTP !
  • 90. POST CREATE UPDATE CRUD READ DELETE HTTP !
  • 91. POST CREATE UPDATE CRUD READ GET DELETE HTTP !
  • 92. POST PUT CREATE UPDATE CRUD READ GET DELETE HTTP !
  • 93. POST PUT CREATE UPDATE CRUD READ GET DELETE DELETE HTTP !
  • 94. http://www.snowflake.org/people/1
  • 95. UNIVERSAL URI IDE NT IFI ER RESOURCE
  • 96. ADD POST /people
  • 97. ADD POST /people SEE GET /people
  • 98. ADD POST /people SEE GET /people CHANGE PUT /people/1
  • 99. ADD POST /people SEE GET /people CHANGE PUT /people/1 REMOVE DELETE /people/1
  • 100. REPRESENTATIONAL STATE TRANSFER REST
  • 101. RAILS CONTROLLER ACTIONS
  • 102. RAILS CONTROLLER ACTIONS INDEX NEW EDIT SHOW CREATE UPDATE DESTROY
  • 103. Building something...
  • 104. Let’s get started
  • 105. Choose a subject
  • 106. 2 hrs IT WON’T BE ENOUGH...
  • 107. First 15 minutes ■ 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 1 Student * Beer
  • 108. 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
  • 109. mate .
  • 110. App structure - app - models - views - controllers - config - db - migrate
  • 111. App structure - app - models the model files - views - controllers - config - db - migrate
  • 112. App structure - app - models the model files - views templates for HTML - controllers - config - db - migrate
  • 113. App structure - app - models the model files - views templates for HTML - controllers the controller files - config - db - migrate
  • 114. App structure - app - models the model files - views templates for HTML - controllers the controller files - config basic configuration - db - migrate
  • 115. App structure - app - models the model files - views templates for HTML - controllers the controller files - config basic configuration - db - migrate database migrations
  • 116. Migrations
  • 117. db/migrate/00000000_create_people.rb class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name t.timestamps end end def self.down drop_table :people end end
  • 118. Create a ‘People’ db/migrate/00000000_create_people.rb table on UP class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name t.timestamps end end def self.down drop_table :people end end
  • 119. Create a ‘People’ db/migrate/00000000_create_people.rb With a ‘Name’ table on UP String class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name t.timestamps end end def self.down drop_table :people end end
  • 120. Create a ‘People’ db/migrate/00000000_create_people.rb With a ‘Name’ table on UP String class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name t.timestamps end end def self.down drop_table :people And some time-stamps: end end created_at & updated_at
  • 121. Create a ‘People’ db/migrate/00000000_create_people.rb With a ‘Name’ table on UP String class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name t.timestamps end end def self.down drop_table :people And some time-stamps: end end created_at & updated_at Drop the table on DOWN
  • 122. Relationships
  • 123. 1 Student * Beer app/models/student.rb class Student < ActiveRecord::Base has_many :beers end app/models/beer.rb class Beer < ActiveRecord::Base belongs_to :student end
  • 124. db/migrate/00000000_create_beers.rb class 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 end end
  • 125. db/migrate/00000000_create_beers.rb Add a reference to Student (:student_id) class 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 end end
  • 126. 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 migrations t.references :student
  • 127. 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
  • 128. Routes
  • 129. 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 => quot;welcomequot; map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end
  • 130. config/routes.rb Routes for each resource 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 => quot;welcomequot; map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end
  • 131. config/routes.rb Routes for each resource 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 => quot;welcomequot; map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end Remove # and change :controller to ‘students’
  • 132. ADD POST /people SEE GET /people CHANGE PUT /people/1 REMOVE DELETE /people/1 SEE GET /people/1 CHANGE GET /people/1/edit ADD GET /people/new
  • 133. Next 5 minutes ■ Change the routes Uncomment & choose default controller ■ Remove ‘public/index.html’ $ rm public/index.html ■ Refresh your browser
  • 134. ActiveRecord
  • 135. One class per table One instance per row
  • 136. One class per utable b tes at tri sare lumn Co One instance per row
  • 137. Student.find_by_name(“Andre”) Student.find(:first, :conditions => [“name = ?”,”Andre”])
  • 138. Student.find_all_by_name(“Andre”) Student.find(:all, :conditions => [“name = ?”,”Andre”])
  • 139. andre = Student.new( :name => “Andre” ) andre.save
  • 140. 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”
  • 141. Views
  • 142. 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 quot;Createquot; %> </p> <% end %> <%= link_to 'Back', beers_path %>
  • 143. Title of the page 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 quot;Createquot; %> </p> <% end %> <%= link_to 'Back', beers_path %>
  • 144. Title of the page app/views/beer/new.html.erb A form <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 quot;Createquot; %> </p> <% end %> <%= link_to 'Back', beers_path %>
  • 145. Title of the page app/views/beer/new.html.erb A form <h1>New beer</h1> <% form_for(@beer) do |f| %> <%= f.error_messages %> <p> <%= f.label :brand %><br /> <%= f.text_field :brand %> Show errors messages if </p> <p> something goes wrong <%= f.submit quot;Createquot; %> </p> <% end %> <%= link_to 'Back', beers_path %>
  • 146. Title of the page app/views/beer/new.html.erb A form <h1>New beer</h1> <% form_for(@beer) do |f| %> <%= f.error_messages %> <p> <%= f.label :brand %><br /> <%= f.text_field :brand %> Show errors messages if </p> <p> something goes wrong <%= f.submit quot;Createquot; %> Some fields </p> <% end %> and a button <%= link_to 'Back', beers_path %>
  • 147. Title of the page app/views/beer/new.html.erb A form <h1>New beer</h1> <% form_for(@beer) do |f| %> <%= f.error_messages %> <p> <%= f.label :brand %><br /> <%= f.text_field :brand %> Show errors messages if </p> <p> something goes wrong <%= f.submit quot;Createquot; %> Some fields </p> <% end %> and a button <%= link_to 'Back', beers_path %> Back link
  • 148. 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 quot;Createquot; %> </p> <% end %> <%= link_to 'Back', beers_path %>
  • 149. 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 quot;Createquot; %> </p> <% end %> <%= link_to 'Back', beers_path %>
  • 150. 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 objects Change 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!
  • 151. Validations This is a behaviour...
  • 152. Validations This is a behaviour...
  • 153. BDD BEHAVIOUR DRIVEN DEVELOPMENT
  • 154. How should a student behave?
  • 155. Student ■ should never have a blank name
  • 156. Terminal
  • 157. 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
  • 158. 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
  • 159. 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
  • 160. spec/models/student_spec.rb require File.dirname(__FILE__) + '/../spec_helper' describe Student do it quot;should never have a blank namequot; do no_name = Student.new( :name => “” ) no_name.should_not be_valid end end
  • 161. spec/models/student_spec.rb ActiveRecord objects require File.dirname(__FILE__) + '/../spec_helper' describe Student do have a valid? method it quot;should never have a blank namequot; do no_name = Student.new( :name => “” ) no_name.should_not be_valid end end
  • 162. require File.dirname(__FILE__) + '/../spec_helper' describe Student do it quot;should never have a blank namequot; do no_name = Student.new( :name => “” ) no_name.should_not be_valid end end Terminal: Running tests
  • 163. require File.dirname(__FILE__) + '/../spec_helper' describe Student do it quot;should never have a blank namequot; do no_name = Student.new( :name => “” ) no_name.should_not be_valid end end 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
  • 164. app/models/student.rb class Student < ActiveRecord::Base has_many :beers validates_presence_of :name end
  • 165. app/models/student.rb class Student < ActiveRecord::Base has_many :beers validates_presence_of :name end
  • 166. 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. require File.dirname(__FILE__) + '/../spec_helper' describe Student do end ■ Build the test database rake db:migrate RAILS_ENV=test
  • 167. Next 15 minutes ■ Spec out all your validations ■ First, all your specs should fail ■ Add the validations to your models validates_presence_of validates_uniqueness_of validates_format_of validates_length_of validates_numericality_of ■ Then, all your specs should pass
  • 168. Connecting dots
  • 169. ............. Connecting dots
  • 170. Let’s make our view a little bit more fun
  • 171. app/views/students/show.html.erb <p> <b>Name:</b> <%=h @student.name %> </p> <%= link_to 'Edit', edit_person_path(@person) %> | <%= link_to 'Back', people_path %>
  • 172. 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 %>
  • 173. Next 10 minutes ■ Pimp one of your views!
  • 174. You all get a PDF version of this book to continue working on your project, thanks to pragprog.com FREE!
  • 175. </PRESENTATION>