40
1.9.2 3.0.5 Ruby on Rails 101 @claytonlz - Desert Code Camp 2011.1 - http://spkr8.com/t/7007 Saturday, April 2, 2011

Ruby on Rails 101

Embed Size (px)

Citation preview

Page 1: Ruby on Rails 101

1.9.2

3.0.5

RubyonRails 101

@claytonlz - Desert Code Camp 2011.1 - http://spkr8.com/t/7007

Saturday, April 2, 2011

Page 2: Ruby on Rails 101

EcosystemModelsControllersViewsDeploying & OptimizingResources for Learning

Saturday, April 2, 2011

Page 3: Ruby on Rails 101

Community

Saturday, April 2, 2011

Page 4: Ruby on Rails 101

“This sure is a nice fork, I bet I could… HOLY

SHIT A KNIFE!”

Saturday, April 2, 2011

Page 5: Ruby on Rails 101

Opinionated

Saturday, April 2, 2011

Page 6: Ruby on Rails 101

“I flippin’ told you MVCis the only way to buildweb apps! Teach you to

doubt DHH!”

Saturday, April 2, 2011

Page 7: Ruby on Rails 101

Rapid Development

Saturday, April 2, 2011

Page 8: Ruby on Rails 101

“These goats are okay, but I really need a yak

for some quality shaving”

Saturday, April 2, 2011

Page 9: Ruby on Rails 101

EcosystemModelsControllersViewsDeployingResources for Learning

Saturday, April 2, 2011

Page 10: Ruby on Rails 101

Models

AssociationsValidationsCallbacksQuerying

Saturday, April 2, 2011

Page 11: Ruby on Rails 101

Models

ActiveRecord::Baseclass Product < ActiveRecord::Base ...end

productsproductsname string

sku string

price decimal

Saturday, April 2, 2011

Page 12: Ruby on Rails 101

Models ➤ Associations# manufacturerhas_many :products

# producthas_one :upcbelongs_to :manufacturerhas_many :batcheshas_many :ingredients, :through => :batches

# batchbelongs_to :productbelongs_to :ingredient

# ingredienthas_many :batcheshas_many :products, :through => :batches

products

manufacturersupcs

batches

ingredients

Saturday, April 2, 2011

Page 13: Ruby on Rails 101

Models ➤ Associations

# create a product and find its manufacturerproduct = manufacturer.products.create({:name => "Kitlifter"})product.manufacturer

# create a upc and find its product's manufacturerupc = product.create_upc({:code => "001122"})upc.product.manufacturer

# create a batch (linking a product and ingredient)wheat = Ingredient.create({:name => "Wheat"})bread = Product.create({:name => "Bread"})

batch.create({:product => bread, :ingredient => wheat})

Saturday, April 2, 2011

Page 14: Ruby on Rails 101

Models ➤ Associations

“Using has_many or belongs_to is more than just on which table the foreign key is placed,

itʼs a matter of who can be thought of as ʻowningʼ the other. A product ʻownsʼ a UPC.”

When should I use has_oneand belongs_to?

Saturday, April 2, 2011

Page 15: Ruby on Rails 101

Models ➤ Validations

class Product < ActiveRecord::Base validates_presence_of :name validates_uniqueness_of :name validates_format_of :sku, :with => /^SKU\d{8}$/ validates_inclusion_of :usda_rating, :in => %w( prime choice ) validate :cannot_be_active_if_recalled def cannot_be_active_if_recalled if recalled? && recalled_on < Date.today errors.add(:active, "Can't be active if it's been recalled") endend

Saturday, April 2, 2011

Page 16: Ruby on Rails 101

Models ➤ Validations

“It is possible to save a record, without validating, by using save(:validate => false)”

I know my record istechnically invalid, butI want to save it anyhow.

Saturday, April 2, 2011

Page 17: Ruby on Rails 101

Models ➤ Callbacks

class Ingredient before_destroy :determine_destroyability before_create :format_legacy_name after_update :log_changes after_create :import_harvest_data # validation # create # save # update # destroy end

Callback Chain

STOP!!

determine_destroyability

Saturday, April 2, 2011

Page 18: Ruby on Rails 101

Models ➤ Querying

Product.find(98)Product.find_by_name("Diet Coke")Product.find_by_name_and_sku("Diet Coke", "SKU44387")Product.find([98,11,39])Product.firstProduct.lastProduct.allProduct.count

# old and bustedProduct.find(:all, :conditions => {:name => "Cheese-it!"})

# new hotnessProduct.where(:name => "Cheese-it!").all

Saturday, April 2, 2011

Page 19: Ruby on Rails 101

Models ➤ QueryingProduct.where("name = ?", 'Skittles')Product.where(:created_at => Date.yesterday..Date.today)Product.where(:sku => ["SKU912", "SKU187", "SKU577"])

Product.order('name DESC')

Product.select('id, name')

Product.limit(5)

# chainableProduct.where(:created_at => Date.yesterday..Date.today) .limit(10) Product.order('created_at ASC').limit(20).offset(40)

Product.select('created_at').where(:name => 'Twix')

Saturday, April 2, 2011

Page 20: Ruby on Rails 101

Models ➤ Queryingmanufacturer.includes(:products) .where('products.usda_rating = ?', 'prime')

manufacturer.includes(:products) .where(:state => 'AZ') .order('created_at') manufacturer.includes(:products => :ingredients) .where('ingredients.name = ?', 'glucose') .order('updated_at') manufacturer.joins(:products) .where('products.sku = ?', 'SKU456') ingredient.includes(:products => {:manufacturer => :conglomerate}) .where('conglomerates.name = ?', 'nestle') animalia.includes(:phylum => {:class => {:order => {:family => :genus}}})

child.includes(:parent => [:brother, {:sister => :children}])

Saturday, April 2, 2011

Page 21: Ruby on Rails 101

Models ➤ Validations

“Using includes will load the records into memory when the query

is executing, joins will not.”

Why would I use joinsinstead of includes?

Saturday, April 2, 2011

Page 22: Ruby on Rails 101

Controllers

RoutingFiltersConventions

Saturday, April 2, 2011

Page 23: Ruby on Rails 101

Controllers ➤ Routingresources :products# GET /products => index action# GET /products/new => new action# GET /products/:id => show action# GET /products/:id/edit => edit action## POST /products => create action# # PUT /products/:id => update action## DELETE /products/:id => destroy action

products_path # /productsproducts_url # http://www.example.com/products

product_path(@product) # /products/29product_path(@product, :xml) # /products/29.xml

Saturday, April 2, 2011

Page 24: Ruby on Rails 101

Controllers ➤ Routing

namespace :admin do resources :users resources :ordersend

admin_users_path # /admin/usersedit_admin_order_path # /admin/orders/4/edit

class Admin::UsersController < ApplicationController # /app/controllers/admin/users_controller.rb # /app/views/admin/users/end

Saturday, April 2, 2011

Page 25: Ruby on Rails 101

Controllers ➤ Routingresources :accounts, :except => :destroy do resources :users do post :activate, :on => :member collection do get 'newest' end end resources :clients, :only => [:index, :show]end

account_users_path(@account) # /accounts/182/usersnewest_account_users_path(@account) # /accounts/182/users/newestactivate_account_user_path(@account, @user) # /accounts/182/user/941

accounts_clients_path(@account) # /accounts/182/clientsnew_accounts_client_path(@account) # FAIL!

Saturday, April 2, 2011

Page 26: Ruby on Rails 101

Controllers ➤ Filters

class UsersController < ApplicationController before_filter :load_manufacturer before_filter :find_geo_data, :only => [:show] skip_before_filter :require_login after_filter :log_accessend

# in ApplicationControllerdef log_access Rails.logger.info("[Access Log] Users Controller access at #{Time.now}")end

Saturday, April 2, 2011

Page 27: Ruby on Rails 101

Controllers ➤ Conventionsclass ProductsController < ApplicationController def index # GET /products end def show # GET /products/:id end def new # GET /products/new end def create # POST /products end def edit # GET /products/:id/edit end def update # PUT /products/:id end def destroy # DELETE /products/:id endend

def update # ... update occurred @parent.children.each ...end

def edit @product = Product.find(params[:id])end

def show @product = Product.find(params[:id])end

def destroy @product = Product.find(params[:id])end

before_filter :load_product

Saturday, April 2, 2011

Page 28: Ruby on Rails 101

Controllers ➤ Conventionsclass ProductsController < ApplicationController def index # GET /products end def show # GET /products/:id # renders /app/views/products/show.format end def new # GET /products/new end def create # POST /products redirect_to products_url end def edit # GET /products/:id/edit end def update # PUT /products/:id end def destroy # DELETE /products/:id endend

def update # ... update occurred @parent.children.each ...end

def edit @product = Product.find(params[:id])end

def show @product = Product.find(params[:id])end

def destroy @product = Product.find(params[:id])end

before_filter :load_product

Saturday, April 2, 2011

Page 29: Ruby on Rails 101

Views

Layouts & HelpersFormsPartialsActionView Helpers

Saturday, April 2, 2011

Page 30: Ruby on Rails 101

Views ➤ Layouts & Helpers

<!-- app/views/products/show.html.erb --><h2><%= @product.name %></h2><p>Price: <%= @product.price %></p>

<!-- app/layouts/application.html.erb --><div id="container"> <%= yield %></div>

<div id="container"> <h2>Pop-Tarts</h2> <p>Price: $3.99</p></div>

def show @product = Product.find(params[:id])end M C

V

Saturday, April 2, 2011

Page 31: Ruby on Rails 101

Views ➤ Layouts & Helpers<h2><%= @product.name %></h2><p>Price: <%= number_to_currency(@product.price) %></p><p>Ingredients: <%= @product.ingredients.present? ? @product.ingredients.map(&:name).join(',') : 'N/A' %></p>

# app/helpers/products_helper.rbdef display_ingredients(ingredients) return "N/A" if ingredients.blank? ingredients.map(&:name).join(',')end

<h2><%= @product.name %></h2><p>Price: <%= number_to_currency(@product.price) %></p><p>Ingredients: <%= display_ingredients(@product.ingredients) %></p>

Saturday, April 2, 2011

Page 32: Ruby on Rails 101

Views ➤ Forms

<%= form_tag search_path do %> <p> <%= text_field_tag 'q' %><br /> <%= submit_tag('Search') %> </p><% end %>

<form action="/search" method="post"> <p> <input type="text" name="q" value="" id="q" /> <input type="submit" name="commit_search" value="Search" id="commit_search" /> </p></form>

Saturday, April 2, 2011

Page 33: Ruby on Rails 101

Views ➤ Forms<h2>New Product</h2><%= form_for(@product) do |f| %> <!-- action => /products/:id --> <!-- method => POST --> <p> <%= f.text_field :name %> </p> <p> <%= f.check_box :active %> </p><% end %>

<h2>Edit Product</h2><%= form_for(@product) do |f| %> <!-- action => /products/:id --> <!-- method => PUT --> <p> <%= f.text_field :name %> </p> <p> <%= f.check_box :active %> </p><% end %>

← New Record

Existing Record →

Saturday, April 2, 2011

Page 34: Ruby on Rails 101

Views ➤ Forms

<%= f.hidden_field :secret %><%= f.password_field :password %><%= f.label :name, "Product Name" %><%= f.radio_button :style, 'Clear' %><%= f.text_area, :description %><%= f.select :condition, ["Good", "Fair", "Bad"] %>

<%= f.email_field :user_email %><%= f.telephone_field :cell_number %>

Saturday, April 2, 2011

Page 35: Ruby on Rails 101

Views ➤ Partials

<% @products.each do |product| %> <tr><td><%= link_to(product.title, product_path(product)) %></td></tr><% end %>

<% @products.each do |product| %> <%= render :partial => 'product_row', :locals => {:product => product} %><% end %>

<!-- app/views/products/_product_row.html.erb --><tr><td><%= link_to(product.title, product_path(product)) %></td></tr>

<%= render :partial => 'product_row', :collection => @products, :as => :product %>

Saturday, April 2, 2011

Page 36: Ruby on Rails 101

Views ➤ Partials

<!-- app/views/shared/_recent_changes.html.erb --><ul> <li>...</li> <li>...</li></ul>

<!-- app/views/reports/index.html.erb --><%= render :partial => 'shared/recent_changes' %>

<!-- app/views/pages/news.html.erb --><%= render :partial => 'shared/recent_changes' %>

<%= render :partial => @product %><%= render(@product) %>

<%= render 'bio', :person => @john %>

Saturday, April 2, 2011

Page 37: Ruby on Rails 101

Views ➤ Partials

NumberHelperTextHelperFormHelperJavaScriptHelperDateHelperUrlHelperCaptureHelperSanitizeHelper

Saturday, April 2, 2011

Page 38: Ruby on Rails 101

Deploying & Optimizing

Heroku

NewRelicPassenger

Saturday, April 2, 2011

Page 39: Ruby on Rails 101

Resources for Learning

Video

PeepCode

RailsCasts

CodeSchool

Books

The Rails Way

Beginning Ruby

Ruby for _________Other

PHX Rails User Group

Gangplank

Saturday, April 2, 2011

Page 40: Ruby on Rails 101

@claytonlzhttp://spkr8.com/t/7007

Saturday, April 2, 2011