Demoing rails


Published on

For a demo to some colleagues, I created a Ruby on Rails demonstration. This document shows a scenario to build a very simple webshop. See for the full story.

Published in: Technology, Business
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Demoing rails

  1. 1. Demoing Rails Stuff in keynote in black on white Stuff to show in white on black Ruby recap Keynote: Short Ruby recap My first app Create an empty Ruby application Start it, and show in a browser (localhost:3000) Keynote: Our case: a webshop Generate the Articles controller Create & migrate the database Create some article by going to localhost:3000/articles Keynote: What has rails built for us? (M/V/C) (plus: config, db, public, scripts, test) Keynote: Rails & Rest p.1
  2. 2. Layouts Keynote: Layouts Build the default layout based on the existing layout, set it as default in application.rb, and add some stylings app/views/layouts/default.html.erb <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""> <html xmlns="" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <title>Articles: <%= controller.action_name %></title> <%= stylesheet_link_tag 'scaffold', 'webshop' %> </head> <body> <div id="header"> <h1>Welcome to our webshop!</h1> </div> <div id="menubar"> <h3>Shopping cart</h3> </div> <p style="color: green"><%= flash[:notice] %></p> <div id="body"> <%= yield %> </div> </body> app/controllers/application_controller.rb class ApplicationController < ActionController::Base layout 'default' p.2
  3. 3. public/stylesheets/webshop.css #header { background-color: green; padding: 10px; } #menubar { float: left; background-color: green; width: 200px; } #body { float: left; padding: 10px; } Simple security Keynote: Filters Create authentication filter for the articles controller, except ʻshowʼ app/controllers/articles_controller.rb class ArticlesController < ApplicationController before_filter :authenticate, :except => 'show' ... private def authenticate authenticate_or_request_with_http_basic do |username, password| username == 'admin' && password == 'secret' @admin = true end end end Show that we now need to log in; log in in one browser, and donʼt in another Also, show that there is now a ʻfilter chain haltedʼ in the server log Remove the ʻeditʼ link form the show.html. app/views/articles/show.html.erb delete: <%= link_to 'Edit', edit_article_path(@article) %> | p.3
  4. 4. The shop controller Keynote: Shop controller Generate the shop controller Put some basic index in the shop controller , noting that we want to show the app/controllers/shop_controller.rb class ShopController < ApplicationController def index @articles = Article.all end end Create some contents for the shop/index app/views/shop/index.html.erb <marquee><b>Our thingies are priced to move!</b></marquee> <%= render :partial => @articles %> Keynote: Partials (2 slides) Build the _article partial (point out that div_for takes a code block, and we will see this pattern more often. app/views/articles/_article.html.erb <% div_for article do%> <%= link_to_unless_current h(article.title), article %> <%= number_to_currency article.price, :unit => '€'%> <% end %> Show that we now have an operation webshop at localhost:3000/shop Edit routes.rb to make this is default starting point (also, delete public/index.html !) config/routes.rb # You can have the root of your site routed with map.root -- just remember to delete public/index.html. map.root :controller => 'shop' p.4
  5. 5. Buying stuff In article/show, add a new button to buy stuff app/views/articles/show.html.erb <%= button_to 'Buy', :controller => 'shop', :action => 'add_to_cart', :id => @article %> We need an add_to_cart in the shop controller. Explain the ʻparamsʼ and ʻredirectʼ app/controllers/shop_controller.rb class ShopController < ApplicationController def index @articles = Article.all end def add_to_cart @cart.add_item(Article.find(params[:id])) redirect_to :action => :index end end Start building the cart. Keynote: The cart (slide 1). Create a cart and a cart_item. We donʼt use scaffolding, since they are in memory only. p.5
  6. 6. app/models/cart.rb class Cart attr_reader :items def initialize @items = [] end def add_item(article) current_item = @items.find {|cart_item| cart_item.article == article} if current_item current_item.increment else @items << end end end app/models/cart_item.rb class CartItem attr_accessor :article, :amount def initialize(article) @article = article @amount = 1 end def increment @amount += 1 end end Use a before_filter in the application to find the cart when needed app/controllers/application.rb class ApplicationController < ActionController::Base before_filter :find_cart ... private def find_cart session[:cart] ||= @cart = session[:cart] end end p.6
  7. 7. The shopping cart Keynote: The cart (slide 2) Add the shopping cart to the layout app/views/layouts/default.html.erb <div id="menubar"> <h3>Shopping cart</h3> <% if @cart %> <%= render :partial => @cart%> <% end %> </div> Add the shopping cart partial app/views/carts/_cart.html.erb <div id="shoppingcart"> <table> <%= render :partial => 'carts/cart_item', :collection => cart.items %> </table> </div> Create the cart_item partial: show that we have something now app/views/carts/_cart_item.html.erb <tr> <td><%= link_to cart_item.article.title, cart_item.article %></td> <td><%= cart_item.amount %>x</td> </tr> Add some styling for the shopping cart public/stylesheets/webshop.css #shoppingcart { background-color: white; margin: 2px; } Add totals line to _cart app/views/carts/_cart.html.erb <div id="shoppingcart"> <table> <%= render :partial => 'carts/cart_item', :collection => cart.items %> <tr> <td/> <td><%= number_to_currency cart.price, :unit => '€' %></td> </tr> </table> </div> p.7
  8. 8. Add necessary methods to cart & cart_item app/models/cart.rb def price @items.inject(0) {|total, cart_item| total + cart_item.price } end app/models/cart_item.rb def price @article.price * @amount end Ordering Keynote: Recap Rails & rest Add an order button app/views/carts/_cart.html.erb <%= link_to('Order!', :controller => :orders, :action => :new) %> Keynote: Line & Order Create (scaffold) Order & OrderLine, remember rake db:migrate. Remember to remove the new layouts. Show the ʻbelongs_toʼ in OrderLine, and add a has_many to Order p.8
  9. 9. app/models/order.rb class Order < ActiveRecord::Base has_many :order_lines end Add basic security to the orders_controller app/controllers/orders_controller.rb class OrdersController < ApplicationController before_filter :authenticate, :except => ['new', 'create'] ... end And to make that work correctly, move ʻauthenticateʼ to the application controller. Update the order/new to show our cart, and look more like we want it to. app/views/orders/new.html.erb <h3>Here's the cool stuff you bought!</h3> <%= render :partial => @cart %> <h3>Who are you, anyway?</h3> <% form_for(@order) do |f| %> <%= f.error_messages %> <p> <%= f.label :customer %><br /> <%= f.text_field :customer %> </p> <p> <%= f.submit 'Create' %> </p> <% end %> When placing an order, it tells us to log in; thatʼs because of the redirect. Update the ʻcreateʼ method to look like this. app/controllers/orders_controller.rb def create @order =[:order]) @order.fill_from_cart(session[:cart]) if session[:cart].clear flash[:notice] = 'Thank you, come again!' redirect_to :controller => 'shop' else render 'new' end end p.9
  10. 10. Build the ʻfill_from_cartʼ method app/models/order.rb def fill_from_cart(cart) cart.items.each do |item| order_lines << => item.article, :amount => item.amount) end end Add the ʻclearʼ method to the cart app/models/cart.rb def clear @items = [] end The wrapup Keynote: what did we just see? p.10