This document contains notes from a Rails training session. It discusses variables in Ruby and Rails, controllers, testing controllers, associations between database tables, and many-to-many relationships. Key topics covered include using instance variables to share data between models and views, testing controller actions, the params hash, and setting up belongs_to, has_many, has_many :through, and HABTM associations.
4. Variables
foobar # local variable
@foobar # instance variable, starts with @
@@foobar # class variable, starts with @@
$foobar # global variable, starts with $
FOOBAR # Constant, starts with a capitol letter
FooBar # Classes are constants
@Schneems
Friday, June 24, 2011
5. Instance Variables
@color = "blue" color = "pink"
def instance_fur_color def local_fur_color
return @color return color
end end
puts instance_fur_color puts local_fur_color
>> "blue" >> NameError:
undefined local variable
@Schneems
Friday, June 24, 2011
6. Instance Variables
@color = "blue" color = "pink"
def instance_fur_color def local_fur_color
return @color return defined?(color)
end end
puts instance_fur_color >> False
>> "blue"
@Schneems
Friday, June 24, 2011
7. Instance Variables
class Dog
def set_color(color)
@fur_color = color
end
def color
"fur color is #{@fur_color}"
end
end
# create a Dog instance
lassie = Dog.new
# set color
lassie.set_color("brown")
# get @fur_color
lassie.color
>> "@fur_color is brown"
@Schneems
Friday, June 24, 2011
8. Bad Scope
class Circle
$sides = 0
def self.sides
$sides
end
Triangle.sides
end
>> 3
Circle.sides
class Triangle
>> 3
$sides = 3
def self.sides
$sides
end
end
@Schneems
Friday, June 24, 2011
9. Rails - Week 3
• Rails - A Place for Everything
• Public
• Images
• Javascripts
• Stylesheets
@Schneems
Friday, June 24, 2011
11. Controllers
• The C in MVC
• handles buisness logic
htt://localhost:3000/clients/new
class ClientsController < ApplicationController
def new
end
end
@Schneems
Friday, June 24, 2011
12. Controllers
• Pass data to controllers via query
string
htt://localhost:3000/clients?status=activated
?status=activated
?status=activated&level=23
?status=deactivated&level=1&foo=bar
@Schneems
Friday, June 24, 2011
13. Controllers
• params, get data from the url
• instance variables pass data to
view
http://localhost:3000/clients?status=activated
def index
@status = params[:status]
if @status == "activated"
@clients = Client.activated
else
@clients = Client.unactivated
end
end
@Schneems
Friday, June 24, 2011
14. Controllers
• Receive Arrays
Arrays
GET /clients?ids[]=1&ids[]=2&ids[]=3
params[:ids] # => [“1”,”2”,”3”]
@Schneems
Friday, June 24, 2011
17. Rails - Week 3
• Functional Testing - Controllers
• web request successful?
• user redirected to the right page?
• user successfully authenticated?
• correct object stored in the template?
• appropriate message displayed to the user ?
@Schneems
Friday, June 24, 2011
18. Rails - Week 3
• Use HTTP to send data to controller
• get, post, put, head, delete
• Verify Response
• Assigns
• Cookies
• Flash
• Session
@Schneems
Friday, June 24, 2011
19. Cookies?
• Stored on the user’s computer
• Mostly used for settings
cookies["remember_me"] = true
@Schneems
Friday, June 24, 2011
20. Session?
• store and access user specific data
• Uses cookies to store data by default
• very quick, and secure
• NOT for critical information
• Put it in the database
session[:logged_in] = true
session[:user_id] = 57
session[:is_mobile] = false
@Schneems
Friday, June 24, 2011
21. Flash?
• Part of the session
• cleared after each request
• useful for error messages
@Schneems
Friday, June 24, 2011
22. Flash?
flash[:notice] = "You must sign in to see this page."
or
redirect_to signup_url,
:notice => "You must sign in to see this page."
@Schneems
Friday, June 24, 2011
23. Rails - Week 3
• Functional Testing - Controllers
• Send data to controller
• Verify response
class PetControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
end
end
@Schneems
Friday, June 24, 2011
24. Rails - Week 3
• Use HTTP to send data
• Get, Post, Put, Delete
Controller
• assigns(:post) = @post
def create
@post = Post.create(params[:post])
end
Test
post :create, :post => { :title => 'Some title'}
assert assigns(:post).is_a?(Post)
@Schneems
Friday, June 24, 2011
25. Rails - Week 3
• Assert difference
assert_difference('Post.count', 1) do
post :create, :post => { :title => 'Some title'}
end
@Schneems
Friday, June 24, 2011
27. Associations
• Relational Databases
• Primary Key
• unique key can identify
each row in a table
• Foreign Key
• Relates a row keyanother
row’s primary
to
@Schneems
Friday, June 24, 2011
28. Primary Key
• Unique identifier for all objects
Hats:
id: 557
style: "Fedora"
Hats:
id: 687
style: "Cowboy"
@Schneems
Friday, June 24, 2011
29. Foreign Key
• Relates to another row’s primary key
Hats
id: 557
style: "Fedora"
inspector_id: 35
Inspectors
id: 35
name: "John"
@Schneems
Friday, June 24, 2011
32. Has_Many
• has_many :child_class
• Builds Association in Ruby
i.e. Hat inspector has many hats
@Schneems
Friday, June 24, 2011
33. Has_Many
• How Does this Help?
• Related objects contain links to one
another
• Get one object, you’ve got all associated
>> myCustomer = Customer.where(:id => 2)
>> orders = myCustomer.orders.all
@Schneems
Friday, June 24, 2011
34. Has_Many
• Caveats
• myCustomer.orders builds SQL and hits the database
• N+1 Problem - Imagine
• You query 100 customers
• Each Customer has 100 orders
• Each Order has 100 products
• ...
@Schneems
Friday, June 24, 2011
35. Associations
• N+1 - (Cont.)
customers = Customer.all
customers.each do |customer|
customer.orders do |order|
order.products do |product|
puts product
end
end
This would generate 10,001 database queries
(not a good thing)
@Schneems
Friday, June 24, 2011
36. Associations
• N+1 - How do we Fix it?
• What if we could Pre-load Associations?
• Includes
Customer.includes(:orders => :products).all
This would generate 1 database query!!
Will take significantly less time than alternative
Note: database access is almost always be your bottleneck
@Schneems
Friday, June 24, 2011
37. Has_Many :Through =>
• Chain Associations Using :Through
What Classes have foreign keys?
@Schneems
Friday, June 24, 2011
38. Has_Many :Through =>
• Appointments
• physician_id
• patient_id
What Classes have foreign keys?
@Schneems
Friday, June 24, 2011
39. Has_Many :Through =>
• Physician Class
• Uses Appointments
• Finds Patients
• Automatically
>> dr = Physicians.first
>> dr.patients
@Schneems
Friday, June 24, 2011
40. Has & Belongs To Many
• HABTM (has and belongs to many)
• Creates direct many to many relationship
This is essentially using :through with a
@Schneems
single purpose table: assemblies_parts
Friday, June 24, 2011
41. HABTM - Vs. :Through
• Use HABTM
• Don’t need to do anything with the relationship
model
• Restricted DB size
• Use :through
• Need validations
• Need callbacks
• Need extra attributes
@Schneems
Friday, June 24, 2011
42. Questions?
http://guides.rubyonrails.org
http://stackoverflow.com
@Schneems
Friday, June 24, 2011