rails 3 beginner to builder 2011 week 5
DESCRIPTION
This is the 5th of 8 presentations given at University of Texas during my Beginner to Builder Rails 3 Class. For more info and the whole series including video presentations at my blog: http://schneems.com/tagged/Rails-3-beginner-to-builder-2011TRANSCRIPT
July, 2011
Beginner to BuilderWeek 5
Friday, July 8, 2011
@Schneems
Reminder• Ethan Waldo
• @EthanWaldo
• Here to help answer questions
• Say “hi”
Friday, July 8, 2011
@Schneems
Rails - Week 5• Data Flow
• View to Controller
• Routes
• Params
• Authenticating Users
• Cryptographic Hashes (cool huh)
• Authlogic
Friday, July 8, 2011
@Schneems
RESTful
• The state of the message matters
• Different state = different message
REpresentational State Transfer
“You Again?” “You Again?”
Friday, July 8, 2011
@Schneems
RESTful• Rails Maps Actions to HTTP Methods
• GET - index, show, new
• PUT - update
• POST - create
• DELETE - destroy
REpresentational State Transfer
Friday, July 8, 2011
• Documentation
• ClassName#MethodName
• Dog#show
@Schneems
class Dog
def show
...
end
end
Ruby convention
Friday, July 8, 2011
Routes
• Routes
• Connect controller actions to URLs
• Example: /dogs/show/2
• Will call DogsController#show
• Pass params[:id] = 2
@Schneems
resources :dogs
routes.rb
resources sets up {index, new, create, destroy, edit, update} routes
Friday, July 8, 2011
@Schneems
• _path
• _url
path helpers
<%= dogs_path #=> "/dogs" %>
<%= dogs_url #=> "http://localhost:3000/dogs" %>
Friday, July 8, 2011
• routes.rb
• Specify resources
• forget a route?
• run rake routes
@Schneems
dogs GET /dogs(.:format) {:action=>"index", :controller=>"dogs"} dog POST /dogs(.:format) {:action=>"create", :controller=>"dogs"} new_dog GET /dogs/new(.:format) {:action=>"new", :controller=>"dogs"} edit_dog GET /dogs/:id/edit(.:format) {:action=>"edit", :controller=>"dogs"} dog GET /dogs/:id(.:format) {:action=>"show", :controller=>"dogs"} PUT /dogs/:id(.:format) {:action=>"update", :controller=>"dogs"} DELETE /dogs/:id(.:format) {:action=>"destroy", :controller=>"dogs"}
Routesroutes.rb
Verb Controller
resources :dogs
ActionPathhelper
Friday, July 8, 2011
@Schneems
Routes
Source: http://peepcode.com
Friday, July 8, 2011
@Schneems
• dog_path(@dog) (PUT)
• dogs_path (GET)
• dog_path(@dog) (GET)
• dog_path(@dog) (DELETE)
• dogs_path (POST)
Routes
Name That Action!1.Find the Verb2.Plural or Singular?3.object.id or no args?
Friday, July 8, 2011
@Schneems
Routes• dog_path(@dog) (PUT) Update
• dogs_path (GET) Index
• dog_path(@dog) (GET) Show
• dog_path(@dog) (DELETE) Destroy
• dogs_path (POST) Create
Name That Action!1.Find the Verb2.Plural or Singular?3.object.id or no args?
Friday, July 8, 2011
Routes• How do I define http://localhost:3000/ ?
• Root of your application
@Schneems
root :to => "dogs#index"
routes.rb
Friday, July 8, 2011
Routes• Custom route• when resources don’t do enough use “match”
• Define custom helpers using :as =>
• Use route in view as search_path
@Schneems
match '/foobar/' => 'foo#search', :as => :search
http://guides.rubyonrails.org/routing.html
Friday, July 8, 2011
@Schneems
New - Active Record# New does not save the objectdog = Dog.new(:name => "fido")dog.id>> nil
dog.name>> "fido"
dog.new_record?>> true# must manually call savedog.save>> truedog.id>> 1
Friday, July 8, 2011
@Schneems
Create - Active Record# Create does save the object
dog = Dog.create(:name => "lassie")
dog.id
>> 1
dog.name
>> "lassie"
dog.new_record?
>> false
Friday, July 8, 2011
@Schneems
Data Flow• How do I get data from Server?
• Controller to View
• Instance Variables - @dog
• How do I get data from browser to server?
• View to Controller
• forms, links, buttonsdef create
@dog = Dog.create(params[...
end
<%= @dog.name %>
...
Friday, July 8, 2011
@Schneems
• View to Controller (modify @variable)
• View has @variable which has ID and attributes
• Pass @variable.id and new attributes to controller
• Controller finds object by the ID
• modifies attributes and saves data <%= form_for(@dog) do |f| %>
...
<% end %>
def create
@dog = Dog.create(params[...
end
Data Flow
Friday, July 8, 2011
• Send data using links
• link_to generates a link
• Calls a Controller Method
• Passes data
@Schneems
@dog = Dog.find(:id => 2)
link_to
<%= link_to 'Some Action', @dog %>
Friday, July 8, 2011
• link_to can take a path directly
• So can form_for, form_tag, button_to ...
@Schneems
link_to
<%= link_to 'Link Text', dogs_path %>
<%= link_to 'Link Text', “/dogs” %>
or
Friday, July 8, 2011
• path helper is not needed if using a ruby object
@Schneems
@dog = Dog.new
<%= link_to 'Link Text', @dog %>
# => DogsController#new
@dog = Dog.where(:name => "fido")
<%= link_to 'Link Text', @dog %>
# => DogsController#show
link_to
Friday, July 8, 2011
• What data does the controller see ?
• params returns a hash passed via http request
• :id is the key passed from @dogs@Schneems
<%= link_to 'Link Text', dog_path(@dog) %>
link_to
def show
dog_id = params[:id]
Dog.where(:id => dog_id)
...
end
Friday, July 8, 2011
• Why only pass ID?
• minimize data sent to and from server
• decouple data sent from object
• security & continuity
• http methods don’t natively accept ruby objects
@Schneems
def show
dog_id = params[:id]
Dog.where(:id => dog_id)
...
end
link_to
Friday, July 8, 2011
• Can I send other stuff besides ID?
• You betcha!
• pass additional info into view_helper arguments
• all data is stored in params
@Schneems
<%= link_to "Link Text", search_path(:foo => {:bar => 42} )%>
link_to
meaning_of_life = params[:foo][:bar]
Friday, July 8, 2011
• like link_to except renders as a button
• default HTTP for buttons method is POST
@Schneems
button_to
<%= button_to "Link Text", search_path(:foo => {:bar => 42} )%>
Friday, July 8, 2011
• form_for - view_helper
• generates form for object<%= form_for(@dog) do |f| %>
<div class="field">
<%= f.label :fur_color %><br />
<%= f.text_field :fur_color %>
</div>
...
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Controller View
@Schneems
@dog = Dog.new
@dog.fur_color
form_for
Friday, July 8, 2011
• form_for - view_helper
• Uses object’s current state for submit path
<%= form_for(@dog) do |f| %> <div class="field"> <%= f.label :fur_color %><br /> <%= f.text_field :fur_color %> </div>... <div class="actions"> <%= f.submit %> </div><% end %>
@dog = Dog.new
@Schneems
form_for
Controller View
@dog is a new Dog, so the form will
default to calling the create action
Friday, July 8, 2011
• form_tag - view_helper
• generates form with no object
• needs a path
• Path is set in routes.rb
@Schneems
match '/search/' => 'foo#search', :as => :search
Routes
form_tag
View <% form_tag search_path do %>
Search:
<%= text_field_tag 'query' %>
<%= submit_tag 'Go!!'%>
<% end %>
Friday, July 8, 2011
• Why create & new?
• New then Create
def create
@dog = Dog.create(params[...
end
<%= @dog.name %>
...
@Schneems
Controller Methods
dogs_controller.rb app/views/dogs/new.html.erb
dogs_controller.rb app/views/dogs/create.html.erb
def new
@dog = Dog.new
end
<%= form_for(@dog) do |f| %>
...
<% end %>
Friday, July 8, 2011
• What if I want extra actions?
• Use Index for other stuff ( like search)
• Create your own if you have to
@Schneems
def my_crazy_custom_method
puts "This is OK, but not desirable"
end
Controller Methods
index, new, create, destroy, edit, & update not enough?
Friday, July 8, 2011
@Schneems
Controller Methods• What if I run out of methods
• Already used index, new, create, destroy, edit, & update
• Create a new controller !
• DogRacesController
• DogGroomerController
• etc.
multiple controllers per heavily used models is normal
Friday, July 8, 2011
@Schneems
• How do I get data from browser to server?
• Forms
• form_for
• form_tag
• Links
• Buttons
Data Flow
Friday, July 8, 2011
@Schneems
• Lots of view helpers take data from view to controller
• Pick the one that best suits your needs
• Run out of Routes to use?
• generate a new controller
• Forget a route
• Run: rake routes
Recap
Friday, July 8, 2011
@Schneems
• Cryptographic Hashes
• Authlogic
Authenticating Users
Friday, July 8, 2011
@Schneems
• A function that takes any input and returns a fixed length string
• function is not reversible
• minor changes in input
• major changes in output
• Examples: MD5, SHA1, SHA256
Crypto Hashes
Passwords
a12n2912348...
Friday, July 8, 2011
@Schneems
• Different input
• Different output
Crypto Hashes
myPass
A12D34U...
myD
iffPa
ss
BG123P29...!=
Friday, July 8, 2011
@Schneems
• Same input
• Same output
==
Crypto Hashes
myPass
A12D34U...
myP
ass
A12D34U...
Friday, July 8, 2011
@Schneems
• How does this help with user authentication?
• passwords shouldn’t be stored in a database
• store crypto-hash instead
• The same input produce the same output
• Compare hashed password to stored hash
Crypto Hashes
Friday, July 8, 2011
@Schneems
• Good for more than just users!
• Comparing large datasets for equality
• Authenticate downloaded files,
Crypto Hashes
Friday, July 8, 2011
@Schneems
• Considerations• Collisions - happen
• Rainbow tables - exist
• Timing Attacks - are not impossible
• Don’t use MD5
• Helpful techniques
• “salt” your hashed data
• hash your Hash
Crypto Hashes
Friday, July 8, 2011
@Schneems
• Are Awesome
• Are Useful
Crypto Hashes
Friday, July 8, 2011
• Authentication Gem
• Don’t write your own authentication• Good for learning, but in production use a
library
@Schneems
gem install authlogic
Authlogic
Friday, July 8, 2011
• Very flexible, lightweight, and modular
• Doesn’t generate code, examples are online
@Schneems
class UserSession < Authlogic::Session::Base
end
Authlogicclass User < ActiveRecord::Base
acts_as_authentic
end
Friday, July 8, 2011
• They’re kindof important
@Schneems
Routes
(like, really really important)
Friday, July 8, 2011
@Schneems
Questions?
http://guides.rubyonrails.orghttp://stackoverflow.com
http://peepcode.com
Friday, July 8, 2011