AWD 06: Tarea A: Creando la aplicación - LPC-Ltda/Ruby-on-Rails GitHub Wiki

##6.1 Iteración A1: Creando una aplicación de mantenimiento de productos

Creando una aplicación Rails

$ rails new Depot

##6.2 Creando la base de datos

Si se usa SQLite3 no se necesita hacer nada.

Generando el scaffold

En Rails los modelos usan nombres en singular y las tablas en plural.

Para ingresar comando de varias líneas use un backslash al final de las líneas parciales (no en la última).

$ rails generate scaffold Product \
    title:string description:text image_url:string price:decimal

  invoke  active_record
  create    bd/migrate/20121130000001_create_products.rb
  create    app/models/product.rb
  invoke    test_unit
  create      test/models/product_test.rb
  create      test/fixtures/products.yml
  invoke  resource_route
   route  resources :products
  invoke  jbuilder_scaffold_controller
  create    app/controller/products_controller.rb
  invoke    erb
  create      app/views/products
  create      app/views/products/index.html.erb
  create      app/views/products/edit.html.erb
  create      app/views/products/show.html.erb
  create      app/views/products/new.html.erb
  create      app/views/products/_form.html.erb
  invoke    test_unit
  create      test/controllers/products_controller_test.rb
  invoke    helper
  create      app/helpers/products_helper.rb
  invoke      test_unit
  create        test/helpers/products_helper_test.rb
  invoke    jbuilder
   exist      app/views/products
  create      app/views/products/index.json.jbuilder
  create      app/views/products/show.json.jbuilder
  invoke  assets
  invoke    coffee
  create      app/assets/javascripts/products.js.coffee
  invoke    scss
  create      app/assets/stylesheets/products.css.cscss
  invoke  scss
  create    app/assets/stylesheets/scaffolds.css.cscss

Aplicando la migración

Antes de aplicar la migración definimos que el campo price tendra ocho dígitos significativos y dos después del punto decimal.

[rails40/depot_a/db/migrate/20121130000001_create_products.rb]

class CreateProducts < ActiveRecord::Migration
  def change
    create_table :products do |t|
      t.string :title
      t.text :description
      t.string :image_url
      t.decimal :price, precision: 8, scale: 2
    end
  end
end
$ rake db:migrate

== CreateProducts: migrating ======================================================
-- create_table(:products)
  -> 0.0027s
== CreateProducts: migrated (0.0023s) =============================================

Veamos la lista de productos

$ rails server

[URL: localhost:3000/products]

Para agregar un nuevo producto modificaremos el formulario creado por el scaffold.

[rails40/depot_a/app/views/products/_form.html.erb]

<%= form_for(@product) do |f| %>
  <%= if @product.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@product.errors.count, "error") %>
      prohibited this product from being saved!:</h2>

      <ul>
      <% @product.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description, rows: 6 %>
  </div>
  <div class="field">
    <%= f.label :image_url %><br>
    <%= f.text_field :image_url %>
  </div>
  <div class="field">
    <%= f.label :price %><br>
    <%= f.text_field :price %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

##6.2 Iteración A2: Haciéndo listados más lindos

Para comenzar, modificaremos el archivo en el directorio db llamado seeds.rb.

Agregaremos el código para llenar la table products. Esta usa el método create!() del modelo Product.

Las imágenes que usamos deben estar en el directorio app/assets/images para estar disponibles para la aplicación.

Tenga cuidado: el script seeds.rb remueve la data existente desde products antes de cargar la nueva data.

[rails40/depot_a/db/seeds.rb]

# ... este es un extracto del archivo
Product.create!(title: 'Programing Ruby 1.9 & 2.0',
  description:
    %{<p>
      Ruby is the fastest growing and most exciting dynamic language
      out there. If you need to get working program derivered fast,
      you should add Ruby to your toolbox.
    </p>},
  image_url: 'ruby.jpg',
  price: 49.95)
#...

Note que debido a que usa el método Rails create() levantará una excepción por posibles errores de validación.

Para llenar su tabla products con data de prueba ejecute

$ rake db:seed

Scaffold genera una planilla de estilos para Product que será llenada con los estilos que necesitamos:

[rails40/depot_a/app/assets/stylesheets/products.css.scss]

// Place all the styles related to the Product controller here
// They will automatically be included in application.css.
// You can use Sass (SCSS) here http://sass-lang.com/

.products {
  table {
    border-collapse: collapse;
  }

  table tr td {
    padding: 5px;
    vertical-align: top;
  }

  .list_image {
    width: 60px;
    height: 70px;
  }

  .list_description {
    width: 60%;

    dl {
      margin: 0;
    }

    dt {
      color: #244;
      font-weight: bold;
      font-size: larger;
    }

    dd {
      margin: 0;
    }
  }

  .list_actions {
    font-size: x-small;
    text-align: right;
    padding-left: 1em;
  }

  .list_line_even {
    background: #e0f8f8
  }

  .list_line_odd {
    background: #f8b0f8;
  }
}

Si usted elige bajar este archivo asegúrese que el timestamp este actualizado. Si no, Rails no tomará los cambios hasta que el servidor sea reiniciado. Usted puede actualizar el timestamp grabandolo desde su editor favorito o usando el comando touch.

Las reglas CSS están anidadas, la regla para dl está definida dentro de .list_description, la cual a su vez está definida dentro de products. Esto hace las reglas menos repetitivas, fáciles de leer y mantener.

Usted habrá notado que este archivo termina con scss, usted adivinará que esto significa que el archivo es preprocesado como Sassy CSS (http://sass-lang.com/) antes de ser servido como css.

Ahora debemos relacionar el esta planilla de estilos con las vistas del modelo. Usted no ha encontrado la sección HTML <head> que es donde usualmente esta referencia vive. A cambio, Rails pone un archivo separado que es usado para crear un ambiente de página estándar para toda la aplicación. Este archivo, llamado application.html.erb es un layout de Rails y vive en el directorio layout.

[rails40/depot_a/app/views/layouts/application.html.erb]

<!DOCTYPE html>
<html>
<head>
  <title>Depot</title>
  <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>
</head>
<!-- en el tag body se pone la clase que vincula con la planilla css -->
<body class='<%= controller.controller_name %>'>
<%= yield %>
</body>
</html>

Ya que Rails carga todas las stylesheets de una vez, necesitamos una convención para limitar las reglas para las páginas específicas de un controlador. Usar el controller_name como nombre de clase es una forma simple de lograrlo.

[rails40/depot_a/app/views/products/index.html.erb]

<h1>Listing products</h1>

<table>
<% @products.each do |product| %>
  <tr class="<%= cycle('list_line_odd', 'list_line_even') %>">
    <td>
      <%= image_tag(product.image_url, class: 'list_image') %>
    </td>
    <td class="list_description">
      <dl>
        <dt><%= product.title %></dt>
        <dd><%= truncate(strip_tags(product.description)), length: 80) %></dd>
      </dl>
    </td>
    <td class: "list_actions">
      <%= link_to 'Show', product %>
      <%= link_to 'Edit', edit_product_path(product) %><br/>
      <%= link_to 'Destroy', product, method: :delete, data: {confirm: 'Are you sure' } %>
    </td>
  </tr>
<% end %>
</table>
<br/>
<%= link_to 'New Product', new_product_path %>
  • Las filas en el listado tienen color de fondo alternado. Para esto usamos el método helper llamado cycle().

  • El helper truncate() es usado para desplegar los primeros ochenta caracteres de la descripción. Pero antes de esto llamamos a strip_tags() con el fin de remover los tags HTML de la descripción.

Tiempo de jugar

Para deshacer una migración:

$ rake db:rollback

GIT

$ git config --global --add user.name "Hugo Chinga"
$ git config --global --add user.email [email protected]

Verificamos con

$ git config --global --list
$ git init
$ git add .
$ git commit -m "Depot Scaffold"

Para volver atrás:

$ git checkout .
⚠️ **GitHub.com Fallback** ⚠️