$30 off During Our Annual Pro Sale. View details »

Haciendo Patria (con Sinatra)

febuiles
January 09, 2012

Haciendo Patria (con Sinatra)

Sinatra workshop given at Campus Party '10, Bogotá.

febuiles

January 09, 2012
Tweet

More Decks by febuiles

Other Decks in Programming

Transcript

  1. Haciendo Patria (con Sinatra) Federico Builes 1

  2. 2

  3. 3

  4. http://www.ruby-lang.org/en/downloads/ 4

  5. http://www.mysql.com/downloads/mysql/ 5

  6. http://www.sqlite.org/download.html 6

  7. RubyGems sinatra shotgun dm-core dm-do-adapter dm-migrations dm-timestamps dm-validations dm-sqlite-adapter (dm-mysql-adapter)

    erubis heroku $ gem install [nombre gem] 7
  8. RubyGems [sudo] gem install sinatra shotgun dm-core dm-do-adapter dm-migrations dm-timestamps

    dm- validations dm-sqlite-adapter erubis heroku --no-ri --no-rdoc 8
  9. Código $ git clone git://github.com/febuiles/cp-taller-sample.git $ wget http://github.com/febuiles/cp-taller-sample/zipball/master 9

  10. # garage.rb require "rubygems" require "sinatra" get "/" do "Hola"

    end 10
  11. $ ruby garage.rb # => localhost:4567 $ shotgun garage.rb #

    => localhost:9393 11
  12. GET POST PUT DELETE HEAD OPTIONS 12

  13. get "/items" do # ... end post "/items" do #

    ... end delete "/items" do # ... end 13
  14. GET /items - Lista de todos los items GET /items/new

    - Vista para crear nuevo item GET /items/:id - Vista item específico POST /items - Crea un item nuevo DELETE /items - Elimina un item PUT /items - Compra un item 14
  15. # garage.rb get "/" do end get "/items" do end

    get "/items/new" do end get "/items/:id" do end post "/items" do end delete "/items" do end put "/items" do end 15
  16. get "/items/:id" do end /items/1 /items/foo 16

  17. Item - id PK - title String - author String

    - description Text - price String - category String - sold Boolean 17
  18. # models.rb class Item include DataMapper::Resource property :id, Serial property

    :title, String property :author, String property :description, Text property :category, String property :price, String, :default => "20000" property :sold, Boolean, :default => false end 18
  19. # models.rb require 'dm-core' require 'dm-migrations' require 'dm-validations' configure :development

    do DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/data.db") # DataMapper::setup(:default, "mysql://user:pwd@localhost/mi_db") end class Item include DataMapper::Resource property :id, Serial property :title, String property :author, String property :description, Text property :category, String property :price, String, :default => "20000" property :sold, Boolean, :default => false end Item.auto_upgrade! 19
  20. GET /items - Lista de todos los items GET /items/new

    - Vista para crear nuevo item GET /items/:id - Vista item específico POST /items - Crea un item nuevo DELETE /items - Elimina un item PUT /items - Compra un item 20
  21. # garage.rb require "sinatra" require "models" get "/" do redirect

    "/items" end get "/items" do @items = Item.all erb :index end get "/items/new" do end get "/items/:id" do end post "/items" do end delete "/items" do end ... 21
  22. # views/index.erb <p>Esta es mi venta de garage, hay muchas

    como ella pero esta es la mía.</p> <table> <tr> <th>Producto</th> <th>Autor/Fabricante</th> <th>Vendido?</th> <th>Categoría</th> </tr> <% @items.each do |item| %> <tr> <td><a href="/items/<%= item.id %>"><%= item.title %></a></td> <td><%= item.author %></td> <td><%= item.sold? %></td> <td><%= item.category %></td> </tr> <% end %> </table> <p>Pregunte por lo que no vea. Si está interesado en mi cuerpo también me puede escribir a <a href="federico@mheroin.com">federico@mheroin.com</a>. </p> <p><br/><a href="/items/new">Agregar Producto</a></p> 22
  23. <a href="/items/<%= item.id %>"><%= item.title %></a> <a href="/items/3"><%= item.title %></a>

    23
  24. # models.rb require 'dm-core' require 'dm-migrations' require 'dm-validations' configure :development

    do DataMapper.auto_upgrade! DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/data.db") end class Item include DataMapper::Resource property :id, Serial property :title, String property :author, String property :description, Text property :category, String property :price, String, :default => "20000" property :sold, Boolean, :default => false def sold? sold ? "Si" : "No" end end 24
  25. GET /items - Lista de todos los items GET /items/new

    - Vista para crear nuevo item GET /items/:id - Vista item específico POST /items - Crea un item nuevo DELETE /items - Elimina un item PUT /items - Compra un item 25
  26. # garage.rb ... get "/items/new" do @item = Item.new erb

    :new end ... 26
  27. # /views/new.erb <h2>Nuevo Producto</h2> <form method="POST" action="/items"> <p> <label for="title">Titulo:</label>

    <input type="text" name="title" id="title" value="<%= @item.title %>" /> </p> <p> <label for="author">Autor/Fabricante:</label> <input type="text" name="author" id="fabricante" value="<%= @item.author %>" /> </p> <p> <label for="price">Precio ($):</label> <input type="text" name="price" id="price" value="<%= @item.price %>"/> </p> <p> <label for="category">Categoría:</label> <select name="category"> <option value="Libro">Libro</option> <option value="DVD">DVD</option> <option value="Drogas">Drogas</option> </select> </p> <p> <label for="description">Descripción:</label> <textarea name="description" id="description"><%= @item.description %></textarea> </p> <p><input type="submit" value="Guardar Producto" /></p> </form> 27
  28. <form method="POST" action="/items"> 28

  29. GET /items - Lista de todos los items GET /items/new

    - Vista para crear nuevo item GET /items/:id - Vista item específico POST /items - Crea un item nuevo DELETE /items - Elimina un item PUT /items - Compra un item 29
  30. # garage.rb # params => { :title => Algo, :author

    => "Pepe", :price => "$20000".... } post "/items" do @item = Item.new(params) if @item.save redirect "/items/#{@item.id}" # => /items/1 else erb :new end end 30
  31. # garage.rb # params => { :title => Algo, :author

    => "Pepe", :price => "$20000".... } post "/items" do @item = Item.new(params) if @item.save redirect "/items/#{@item.id}" # => /items/1 else erb :new end end 31
  32. # models.rb # -*- coding: utf-8 -*- class Item include

    DataMapper::Resource property :id, Serial property :title, String property :author, String property :description, Text property :price, String, :default => "20000" property :category, String property :sold, Boolean, :default => false validates_presence_of :title, :message => "El producto necesita un título" validates_presence_of :author, :message => "El producto necesita un autor ó fabricante" validates_presence_of :price, :message => "El precio del producto no puede estar vacío" def sold? sold ? "Si" : "No" end end 32
  33. # /views/new.erb <h2>Nuevo Producto</h2> <% if @item.errors %> <ul class="warning">

    <% @item.errors.each do |error| %> <li><%= error %></li> <% end %> </ul> <% end %> <form method="POST" action="/items"> 33
  34. GET /items - Lista de todos los items GET /items/new

    - Vista para crear nuevo item GET /items/:id - Vista item específico POST /items - Crea un item nuevo DELETE /items - Elimina un item PUT /items - Compra un item 34
  35. # garage.rb get "/items/:id" do @item = Item.get(params[:id]) erb :show

    end 35
  36. # views/show.erb <h2><%= @item.title %></h2> <h3><%= @item.category %></h3> <p><%= @item.description

    %> <em>$<%= @item.price %></em> </p> <p> <%= buy_item_link(@item) %> <%= delete_item_link(@item) %> </p> 36
  37. 37

  38. <form action="/items" method="post"> <input type="hidden" name="_method" value="put" /> <input type="hidden"

    name="id" value="7" /> <input type="submit" value="Comprar" /> </form> <form action="/items" method="post"> <input type="hidden" name="_method" value="delete" /> <input type="hidden" name="id" value="7" /> <input type="submit" value="Eliminar" /> </form> 38
  39. # garage.rb helpers do def buy_item_link(item) html = <<HTML <form

    action="/items" method="post"> <input type="hidden" name="_method" value="put" /> <input type="hidden" name="id" value="#{item.id}" /> <input type="submit" value="Comprar" /> </form> HTML html if !item.nil? end def delete_item_link(item) html = <<HTML <form action="/items" method="post"> <input type="hidden" name="_method" value="delete" /> <input type="hidden" name="id" value="#{item.id}" /> <input type="submit" value="Eliminar" /> </form> HTML html if !item.nil? end end 39
  40. <h2><%= @item.title %></h2> <h3><%= @item.category %></h3> <p><%= @item.description %> <em>$<%=

    @item.price %></em> </p> <p> <%= buy_item_link(@item) %> <%= delete_item_link(@item) %> </p> 40
  41. GET /items - Lista de todos los items GET /items/new

    - Vista para crear nuevo item GET /items/:id - Vista item específico POST /items - Crea un item nuevo DELETE /items - Elimina un item PUT /items - Compra un item 41
  42. # garage.rb delete "/items" do item = Item.get(params[:id]) item.destroy unless

    item.nil? redirect "/items" end 42
  43. # views/index.erb <p>Esta es mi venta de garage, hay muchas

    como ella pero esta es la mía.</p> <table> <tr> <th>Producto</th> <th>Autor/Fabricante</th> <th>Vendido?</th> <th>Categoría</th> </tr> <% @items.each do |item| %> <tr> <td><a href="/items/<%= item.id %>"><%= item.title %></a></td> <td><%= item.author %></td> <td><%= item.sold? %></td> <td><%= item.category %></td> <td><%= buy_item_link(item) unless item.sold %></td> </tr> <% end %> </table> <p>Pregunte por lo que no vea. Si está interesado en mi cuerpo también me puede escribir a <a href="federico@mheroin.com">federico@mheroin.com</a>. </p> 43
  44. GET /items - Lista de todos los items GET /items/new

    - Vista para crear nuevo item GET /items/:id - Vista item específico POST /items - Crea un item nuevo DELETE /items - Elimina un item PUT /items - Compra un item 44
  45. # garage.rb put "/items" do item = Item.get(params[:id]) error 500

    if item.nil? if item.sell @items = Item.all @notice = "Felicitaciones por la compra de: #{item.title}" erb :index else not_found("No encontramos el producto que intentas comprar") end end 45
  46. # models.rb class Item include DataMapper::Resource property :id, Serial property

    :title, String property :author, String property :description, Text property :price, String, :default => "20000" property :category, String property :sold, Boolean, :default => false validates_presence_of :title, :message => "El producto necesita un título" validates_presence_of :author, :message => "El producto necesita un autor ó fabricante" validates_presence_of :price, :message => "El precio del producto no puede estar vacío" def sold? sold ? "Si" : "No" end def sell self.sold = true save end end 46
  47. # garage.rb put "/items" do item = Item.get(params[:id]) error 500

    if item.nil? if item.sell @items = Item.all @notice = "Felicitaciones por la compra de: #{item.title}" erb :index else not_found("No encontramos el producto que intentas comprar") end end 47
  48. # views/index.erb <p>Esta es mi venta de garage, hay muchas

    como ella pero esta es la mía.</p> <% if @notice %> <span class="notice"><%= @notice %></span> <% end %> <table> <tr> <th>Producto</th> <th>Autor/Fabricante</th> <th>Vendido?</th> <th>Categoría</th> </tr> <% @items.each do |item| %> <tr> <td><a href="/items/<%= item.id %>"><%= item.title %></a></td> <td><%= item.author %></td> <td><%= item.sold? %></td> <td><%= item.category %></td> <td><%= buy_item_link(item) unless item.sold %></td> </tr> <% end %> </table> <p>Pregunte por lo que no vea. Si está interesado en mi cuerpo también me puede escribir a <a href="federico@mheroin.com">federico@mheroin.com</a>. </p> 48
  49. # garage.rb require "sinatra" require "models" before do content_type :html,

    :charset => 'utf-8' end get "/" do redirect "/items" end 49
  50. <!-- views/layout.erb --> <html> <head> <link rel="stylesheet" href="/screen.css" type="text/css" media="screen"

    /> <title>Venta de Garage</title> </head> <body> <h1>Venta de Garage</h1> <%= yield %> </body> </html> 50