my cool new slideshow!

of 45/45
Cuatro Dias Cuatro Dias con Rails con Rails compilado por John McCreesh traducción por Emmanuel N. Millán

Post on 15-Jun-2015

135 views

Category:

Technology

1 download

Embed Size (px)

TRANSCRIPT

  • Cuatro DiasCuatro Dias con Railscon Rails

    compilado por John McCreeshtraduccin por Emmanuel N. Milln

  • Tabla de ContenidosIntroduccin ...................................................................................................................................................1

    Da 1 con Rails ...............................................................................................................................................3

    La aplicacin Lista de Tareas .............................................................................................................3Ejecutar el script de Rails ......................................................................................................................3Agregar la aplicacin al servidor Web...............................................................................................3

    Definir la aplicacin en el archivo de hosts ...............................................................................3Definir la aplicacin en el archivo de configuracin de Apache .........................................3Cambiar a fastcgi ................................................................................................................................4Chequear que Rails este funcionando ..........................................................................................4Versiones de Rails ..............................................................................................................................4

    Configurar la Base de Datos .................................................................................................................4Crear la tabla Categorias ..................................................................................................................5

    Definicin MySQL..........................................................................................................................5Modelo de Datos ............................................................................................................................5

    Scaffold .......................................................................................................................................................5Realzar el Modelo .....................................................................................................................................6

    Crear reglas de validacin de datos ..............................................................................................7

    Dia 2 con Rails ...............................................................................................................................................9

    El cdigo generado Scaffold .................................................................................................................9El controlador ......................................................................................................................................9La Vista ................................................................................................................................................11

    Layout .............................................................................................................................................11Template (plantilla) ....................................................................................................................12Partial (parcial) .............................................................................................................................12La vista de renderizado para la accin New....................................................................13Analizando la vista de la accin List...................................................................................14

    Modificar el cdigo generado por Scaffold ...................................................................................16El controlador ....................................................................................................................................16La Vista (View)...................................................................................................................................16

    Mostrar mensajes Flash .............................................................................................................16Compartir variables entre la plantilla y el Layout ............................................................17Atando las pantallas de Edit y New.......................................................................................18

    Da 3 con Rails ............................................................................................................................................19

    La tabla Items .......................................................................................................................................19Definicin MySQL de la tabla ........................................................................................................19El Modelo .............................................................................................................................................19

    Validar los links entre las tablas ............................................................................................20Validar la entrada del usuario .................................................................................................20

    La tabla de Notas .................................................................................................................................20Definicin de la tabla MySQL........................................................................................................20El modelo ............................................................................................................................................21

    Usar un Modelo para mantener Integridad Referencial ..................................................21Mas de Scaffold ......................................................................................................................................22Mas acerca de Vistas .............................................................................................................................22

    Crear un Layout para la Aplicacin ............................................................................................22La pantalla Lista de tareas ...........................................................................................................23

    Eliminar tareas completadas haciendo click en un cono ............................................24Cambiar el modo de ordenamiento haciendo click en el Encabezado de la Columna .........................................................................................................................................24Agregar el Helper ........................................................................................................................25Usar botnes de navegacin Javascript ................................................................................25Formatear una Tabla con un Parcial ......................................................................................25

  • Formato basado en el valor de los Datos ............................................................................27Manejar valores perdidos en una busqueda ......................................................................27

    La pantalla Nueva Tarea ...............................................................................................................27Crear una lista desplegable para el campo fecha ..............................................................28Atrapar excepciones con Ruby ................................................................................................28Crear una lista desplegable desde una tabla de busqueda ............................................29Crear una lista desplegable para la lista de constantes ..................................................29Crear una casilla de verificacin ............................................................................................29

    Toques finales ........................................................................................................................................29Modificar la hoja de estilos ...........................................................................................................29La pantalla Editar Tarea...............................................................................................................30

    Dia 4 con Rails ............................................................................................................................................31

    Las pantallas Notas .............................................................................................................................31Enlazando Notas con Editar Tarea ..........................................................................................31La pantalla Editar Notas ...............................................................................................................32La pantalla de Nota Nueva...........................................................................................................33

    Guardar y traer Datos usando variables de Sesin ...........................................................33Cambiar la pantalla de Categorias .................................................................................................34Navegacin a traves del sistema .......................................................................................................34Descargar una copia de esta aplicacin ..........................................................................................35Y finalmente ............................................................................................................................................35

    Apndice Cambios posteriores ..........................................................................................................37

    Actualizaciones Multiples ...................................................................................................................37View......................................................................................................................................................37Controlador ........................................................................................................................................38Consideraciones de la interfaz de usuario ...............................................................................39

    Todava para hacer ................................................................................................................................39

  • Introduccin

    Han habido varias demandas extravagantes hechas acerca de Rails. Por ejemplo, un articulo publicado en OnLAMP.com 1 demandando que puedes desarrollar una aplicacin web por lo menos diez veces mas rpido con Rails que con un tipico framework Java... El artculo luego muestra como instalar Rails y Ruby en una PC y contruir una aplicacin funcionando con scaffold virtualmente sin cdigo.

    Mientras que esto es impresionante, desarrolladores web reales saben que esto es humo y espejos. aplicacines reales no son tan simples como eso. Qu es realmente lo que esta pasando debajo de la superficie? Qu tan dificil es construir aplicacines web reales?

    Aqui es donde la vida se vuelve un poco difcil. Rails tiene muy buena documentacin on- line, de hecho, posiblemente esta demasiado bien documentado para principiantes, con mas de 30.000 palabras de documentacin on- line en el formato de manual de referencia. Lo que esta faltando en un roadmap (railmap?? - mapa del camino) apuntando a las pginas claves que necesitas saber para comenzar a desarrollar con Rails.

    Este documento est para llenar ese vacio. Asume que ya tienes Ruby y Rails en funcionamiento en una PC (si no has llegado tan lejos, ve devuelta y sigue el articulo de Curt). Esto te lleva al final de Dia 1 con Rails.

    Dia 2 con Rails comienza posicionandose detras del humo y los espejos. Lo lleva a traves del cdigo scaffold. Nuevas caractersticas son remarcadas en negrita, explicadas en el texto, y seguidas por una referencia a la documentacio de Rails o de Ruby donde puedes aprender ms.

    Dia 3 con Rails toma scaffold y comienza a construir algo reconocible como una aplicacin real. Todo el tiempo, esta contruyendo su propia caja de herramientas con Rails. Lo mas importante de todo, deberia tambin sentirse comodo con la documentacin en linea para que pueda continuar con la exploracin usted solo.

    Dia 4 con Rails agrega otra tabla y trata con algunas de las complejidades de mantener la integridad referencial. Al final, tendra una aplicacin en funcionamiento, suficientes herramientas como para comenzar, y el conocimiento de donde buscar mas informacin.

    Diez veces mas rpido? Despus de cuatro dias con Rails, juzguelo por usted mismo!

    Documentacin : este documento contiene referencias destacadas, a cualquiera de los siguientes sitios:

    Docu mentacin La docu mentacin de Rails en h t t p: / / a pi.rubyonrails.com (Esta docu men tacin ta mbin esta instalada en su PC como par te de la ins talacin de gems ubicada en u n lugar como C:\Program Files\ruby\lib\ruby\gems\n.n\doc\actionpack-n.n.n\rdoc\index.html)

    Ruby Docu mentacin Progra m ming Ruby - The Prag matic Progra m mer's Guide disponible en linea y para bajar en h t t p: / / www.ruby - doc.org / docs / r uby - doc -bun dle /Progra m mingRuby /index.ht ml

    1 Rolling with Ruby on Rails, Curt Hibbs 20- Jan2005 http: / / www.onlamp.com / p u b / a / o nla mp / 2 0 05 / 0 1 / 2 0 / r a ils.htm l

    Pgina 1

    http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.htmhttp://www.ruby-doc.org/docs/ruby-doc-bundle/ProgrammingRuby/index.htmlhttp://www.ruby-doc.org/docs/ruby-doc-bundle/ProgrammingRuby/index.htmlhttp://api.rubyonrails.com/
  • Reconocimientos : m uchas gracias a la gente en el canal irc2 y en la lista de correo 3. El regist ro de archivos en linea fue u na invaluable asis tencia mien t ras aprendia Rails y Ruby.

    Versin: 2.3 usando la versin 0.12.1 de Rails vea http: / / r ai ls.homelinux.org para la ltima versin y para bajar una copia del futuro cdigo. Documento escrito y pdf generado con OpenOffice.org 'Writer'.

    Copyright : este trabajo tiene copyright 2005 John McCreesh [email protected] y esta bajo la licencia Creative Commons Attribution-NonCommercial - ShareAlike License . Para ver una copia de esta licencia, visite http: / / c rea tivecommons.org / licenses / by - nc- sa/2.0 / o envie una carta a Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

    2 irc:/ / i rc.freenode.org / r ubyonrails 3 http: / / li s ts.rubyonrails.org /mailman / l is tinfo / rails

    Pgina 2

    http://creativecommons.org/licenses/by-nc-sa/2.0/mailto:[email protected]?subject=Four Days on Railshttp://www.openoffice.org/http://rails.homelinux.org/http://lists.rubyonrails.org/mailman/listinfo/railsfile:///OldToDo/doc/irc://irc.freenode.org/rubyonrails
  • Da 1 con Rails

    La aplicacin Lista de TareasEste docu mento sigue la cons t ruccin de u na si mple aplicacin de lista de tareas el tipo de cosa que tienes en tu PDA, con una lista de ite ms, agrupados en categorias, con no tas opcionales (para ver u na adelan to de como se va a ver, vea Ilustracin 5: La pantallade Lista de Tareas en la pgina 23).

    Ejecutar el script de RailsEste ejemplo esta en mi PC MS- Windows. Mi material de web esta en c:\www\webroot, que etiqueto como mi disco w: para acortar el tipeo:

    C:\> subst w: c:\www\webrootC:\> w:W:\> rails ToDoW:\> cd ToDoW:\ToDo>

    Ejecutar rails ToDo crea un nuevo directorio ToDo\ y lo puebla con una serie de archivos y subdirectorios, los mas importantes de estos son los siguientes:

    appcontiene el nucleo de la aplicacin, dividida en los subdirectorios modelos (model), vistas(view), controladores(controller), y 'ayudantes'(helper)

    config contiene el archivo database.yml que provee detalles de la base de datos a utilizar con la aplicacin

    logregistros especificos de la aplicacin. Nota: development.log mantiene una traza de cada accin que Rails realiza muy util para rastrear errores, pero no necesita ser purgado regularmente!

    publicel directorio disponible para Apache, que incluye imagenes, javascripts, y subdirectorios para stylesheets

    Agregar la aplicacin al servidor WebComo yo estoy ejecutando todo (Apache2, MySQL, etc) en una sola PC de desarrollo, los siguientes dos pasos dan un nombre amigable para la aplicacin en mi navegador.

    Definir la aplicacin en el archivo de hostsC:\winnt\system32\drivers\etc\hosts (fragmento)

    127.0.0.1 todo

    Definir la aplicacin en el archivo de configuracin de ApacheApache2\conf\httpd.conf

    ServerName todo DocumentRoot /www/webroot/ToDo/public Options ExecCGI FollowSymLinks AllowOverride all Allow from all Order allow,deny

    Pgina 3

  • Cambiar a fastcgi

    A menos que sea paciente (o que tenga una PC potente) deberia habilitar fastcgi para esta aplicacin.

    public\.htaccess

    # Para mejor desempeo reemplaze el despachador con el de fastcgiRewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

    Chequear que Rails este funcionando

    El sitio ahora deberia ser visible en su navegador como http://todo/ (debera ver la pgina Congratulations, you've put Ruby on Rails! en su navegador).

    Versiones de Rails

    Para el m o mento que leas este docu men to, Rails p robablemente haya avanzado varias versines. Si intentas avan zar a t raves de este docu men to, chequea la versin ins talada en tu PC:W:\ToDo>gem list --local

    Si son dis tin tas a las versines listadas abajo, entonces yo fuer te mente aconsejaria que baje las versines usadas en Cuat ro dias con Rails, ejem plo: W:\ToDo>gem install rails --versin 0.12.1

    Esto no ro m pera nada; la libreria gems de Ruby es ta diseada para ma nejar m ultiples versines. Entonces p uede for zar a Rails a que use las versines u tilizadas en Cuatro Dias en la aplicacin Lista de Tareas especificando:

    config\environment.rb (fragmento)

    # Require Rails libraries.require 'rubygems'require_gem 'activesupport', '= 1.0.4'require_gem 'activerecord', '= 1.10.1'require_gem 'actionpack', '= 1.8.1'require_gem 'actionmailer', '= 0.9.1'require_gem 'actionwebservice', '= 0.7.1' require_gem 'rails', '= 0.12.1'

    La razn para u sar la mis ma versin es m uy sim ple. Cuat ro Dias usa m ucho cdigo generado auto maticamente po r Rails. Mientras Rails se desar rolla, ta mbin lo hace es te cdigo desafort unada mente, es te docu mento no lo hace (hasta que se p roduce una nueva versin!). Entonces, has tu vida fcil, y m an tene la mis ma versin que se u sa en Cuat ro Dias. Una vez que hayas ter minado de t rabajar con Cuatro Dias, ve a la l ti ma y gran versin de Rails y ve que mejoras los desarrolladores de Rails han realizado.

    Configurar la Base de DatosHe configurado una nueva base de datos llamada todos en MySQL. La conexin a la base de datos es especificada en el archivo config\database.yml

    config\database.yml (fragmento)

    development: adapter: mysql database: todos host: localhost username: foo password: bar

    Pgina 4

  • Crear la tabla Categorias

    La tabla categories (categorias) es utilizada en los ejemplos siguientes. Es una simple lista de categorias que seran usadas para agrupar los items en la Lista de Tareas.

    Definicin MySQL

    Tabla Categories

    CREATE TABLE `categories` ( `id` smallint(5) unsigned NOT NULL auto_increment, `category` varchar(20) NOT NULL default '', `created_on` timestamp(14) NOT NULL, `updated_on` timestamp(14) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `category_key` (`category`)) TYPE=MyISAM COMMENT='List of categories';

    Algunos tips para los nombres de las tablas y campos:

    Guiones bajos en el nombre de los campos seran cambiados por espacios por Rails para obtener nombres amigables al humano

    tener cuidado con la mezcla de mayusculas y minisculas en el nombre del campo algunas partes del cdigo de Rails son sensibles a mayusculas y minisculas.

    Cada tabla deberia tener una clave primaria llamada id - en MySQL es mas fcil tener este campo como un numeric auto_increment

    enlaces a otras tablas deberian seguir la misma convencion de nombre _id Rails automaticamente mantendra los campos llamados created_at/created_on o

    updated_at/updated_on, entonces es una buena idea agregarlos

    Documentacin: ActiveRecord::Timestamp

    Tip til: si esta construyendo un sistema multiusuario (no es relevante aqui), Rails tambin utilizara el bloqueo optimista si agrega un campo llamado lock_versin (integer default 0). Todo lo que necesita recordar es incluir lock_versin como un campo oculto en sus formularios de actualizacin.

    Documentacin: ActiveRecord::Locking

    Modelo de Datos

    Genera un archivo vacio:

    W:\ToDo>ruby script/generate model category exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/category.rb create test/unit/category_test.rb create test/fixtures/categories.yml

    W:\ToDo>

    que crea u n archivo category.rb, y dos archivos de p r ueba category_controller_test.rb y categories.yml. Agregare mos algunas ent radas en el m o delo de da tos en u n minu to dejelo vacio po r el m o mento.

    ScaffoldEl controlador es el corazn de la aplicacin Rails.

    Ejecutar el script generador del controlador

    W:\ToDo>ruby script/generate controller category exists app/controllers/

    Pgina 5

  • exists app/helpers/ create app/views/category exists test/functional/ create app/controllers/category_controller.rb create test/functional/category_controller_test.rb create app/helpers/category_helper.rb

    W:\ToDo>

    que crea dos archivos y dos directorios vacios:

    app\controllers\category_controller.rbapp\helpers\category_helper.rbapp\views\categoriesapp\views\layouts

    Si no ha visto el truco modelo / scaffold en funcionamiento en un tutorial de principiante como Rolling with Ruby on Rails, pruebelo ahora y asombrese de como toda una aplicacin web puede estar escrita en una sola linea de cdigo:

    app\controllers\category_controller.rb

    class CategoryController < ApplicationController scaffold :categoryend

    Documentacin: ActionController::Scaffolding

    Apun te su navegador a http://todo/category y ad mire que tan ingenioso es : - )

    Para averigar que tan ingenioso no es, inten te agregar la mis ma categoria dos veces. Rails f racasar y dara u n sucio mensaje de error ActiveRecord::State men tInvalid in Category#create. Puede ar reglar esto agregando validacin al Modelo.

    Realzar el ModeloEl Modelo es donde toda las reglas relacionadas con datos son guardadas, incluida la validacin y integridad relacional. Esto significa que puede definir una sola regla, y Rails automticamente la aplicar donde sea que el dato es accedido.

    Pgina 6

    Ilustracin 1: pantalla 'Lista' Scaffold

  • Crear reglas de validacin de datos

    Rails otorga mucho manejo de errores gratis (casi). Para demostrar esto, agregue algunas reglas de validacin al modelo de categora vacio:

    app\models\category.rb

    class Category < ActiveRecord::Base validates_length_of :category, :within => 1..20 validates_uniqueness_of :category, :message => "already exists"end

    Estas entradas automaticamente chequearan que:

    validates_length_of: el campo no este en vacio y no sea m uy largo validates_uniqueness_of: valores du plicados son at rapados. No me gus ta el mensaje de

    error por defecto de Rails - xxx has already been taken - entonces doy mi p ropio mensaje. Esta es una caracters tica general de Rails p rimero p r uebe los valores por defecto, si no le gus tan, sobreescribalos.

    Documentacin: ActiveRecord::Validations::ClassMethods

    Pgina 7

  • Para p robar es to, ahora intenta agregar un regist ro d u plicado de nuevo. Esta vez, Rails ma neja el error en vez de rom perse - vea abajo. El estilo es ta un poco en su cara no es la in terfaz de u suario m as sutil. De todas for mas, que espera si es gratis?

    Pgina 8

    Ilustracin 2: Capturando errores de datos

  • Dia 2 con RailsPara progresar mas alla de este punto, necesitamos ver que esta pasando detras de la escena. Durante el dia 2, trabajaremos sistematicamente a traves del cdigo scaffold generado por Rails, decifrando que significa todo. Con la accin scaffold, Rails genera todo el cdigo que necesita dinmicamente. Ejecutando scaffold como un script , podemos obtener todo el cdigo escrito al disco donde lo podemos investigar y luego comenzar a modificarlo para ajustarse a nuestros requerimientos.

    Ejecutar el script generate scaffold

    W:\ToDo>ruby script/generate scaffold category dependency model exists app/models/ exists test/unit/ exists test/fixtures/ skip app/models/category.rb skip test/unit/category_test.rb skip test/fixtures/categories.yml exists app/controllers/ exists app/helpers/ create app/views/categories exists test/functional/ create app/controllers/categories_controller.rb create test/functional/categories_controller_test.rb create app/helpers/categories_helper.rb create app/views/layouts/categories.rhtml create public/stylesheets/scaffold.css create app/views/categories/list.rhtml create app/views/categories/show.rhtml create app/views/categories/new.rhtml create app/views/categories/edit.rhtml create app/views/categories/_form.rhtml

    W:\ToDo>

    Este script genera un rango de archivos necesarios para crear una aplicacin completa, incluyendo un controlador, vistas, layouts, e incluso hojas de estilo (css).

    Note la pequea bizar ra convencin de no mbres nos he mos m ovido del singular a plural, entonces para usar el n uevo cdigo necesita apuntar el navegador a http://todo/categories. De hecho, pa ra evitar confusiones, es mejor borrar app\controllers\category_controller.rb etc en caso de que lo ejecute acciden talmente.

    El cdigo generado Scaffold

    El controlador

    Veamos el cdigo det ras del cont rolador. El cont rolador es don de descansa la p rogra macin lgica de la aplicacin. Interactua con el u suario usando vistas (views), y con la base de datos a t raves de los m o delos (models). Deberia po der leer el cont rolador y ver como la aplicacin esta unida.

    El controlador producido por el script generar scaffold es listado abajo:

    \app\controllers\categories_controller.rb

    class CategoriesController < ApplicationController def index list render_action 'list' end

    def list

    Pgina 9

  • @category_pages, @categories = paginate :category, :per_page => 10 end

    def show @category = Category.find(@params[:id]) end

    def new @category = Category.new end

    def create @category = Category.new(@params[:category]) if @category.save flash['notice'] = 'Category was successfully created.' redirect_to :action => 'list' else render_action 'new' end end

    def edit @category = Category.find(@params[:id]) end

    def update @category = Category.find(@params[:id]) if @category.update_attributes(@params[:category]) flash['notice'] = 'Category was successfully updated.' redirect_to :action => 'show', :id => @category else render_action 'edit' end end

    def destroy Category.find(@params[:id]).destroy redirect_to :action => 'list' endend

    Cuando el usuario de la aplicacin Rails selecciona una accin ejemplo: Show (mostrar) el controlador ejecutar cualquier cdigo de la seccin apropiada def show - y luego por defecto renderizara una plantilla con el mismo nombre - show.rthml. Este comportamiento por defecto puede ser sobreescrito:

    render_template le permite renderizar una plantilla diferente ejemplo: la accin index ejecutara el cdigo de la accin list - def list, y renderizara list.rhtml en vez de index.rhtml (que no existe)

    redirect_to va un nivel mas alla, y utiliza una respuesta externa HTTP 302 moved para volver al controlador ejemplo: la accin destroy no necesita renderizar una plantilla. Despues de realizar su proposito principal (destruir una categoria), simplemente lleva al usuario a la accin list.

    Documentacin: ActionController::Base

    El controlador ActiveRecord usa mtodos como find (encontrar), find_all (encontrar todos), new (nuevo), save (guardar), update_attributes (actualizar atributos), y destroy (destruir) para mover datos a y desde las tablas de la base de datos. Note que no tiene que escribir ninguna sentencia SQL, pero si desea ver que SQL Rails esta usando, esta todo escrito en el archivo development.log.

    Pgina 10

  • Documentacin: ActiveRecord::Base

    Note como una actividad lgica desde la perspectiva del u suario p uede requerir dos pasos a t raves del con trolador: por eje mplo, actualizar un regist ro en la tabla. Cuando el u suario selecciona Edit, el con trolador extrae el regist ro que se desea editar del m o delo, y renderiza la vista edit. Cuando el usuario finalizo la edicin, la vista edit invoca la accin update, que actualiza el m o delo y luego invoca la accin show.

    La Vista

    Las vistas son do nde se define la interfaz del u suario. Rails p uede renderizar la pgina HTML final p resen tada al u suario desde t res co m ponentes:

    Layout Template - Plantilla Partial - Parcial

    en app\views\layouts\

    por defecto: application.rhtml

    o .rhtml

    en app\views\\

    por defecto: .rhtml

    en app\views\\

    por defecto _.rhtml

    Un Layout p rovee cdigo com un usado po r todas las accines, tipicamente el comienzo y final del HTML enviado al navegador.

    Un Tem plate o Plantilla p rovee el cdigo especifico a cada accin, ejem plo cdigo de List, cdigo de Edit, etc.

    Un Partial o Parcial p rovee cdigo co mun - subrutinas - que p uede ser usado en m ultiples accines ejemplo: cdigo usado para m os t rar tablas en u n for m ulario.

    Layout

    Convencin de nombres en Rails: si hay una plantilla en app\views\layouts\ con el mismo nombre que el controlador actual entonces sera utilizada automticamente como layout del controlador a menos que explcitamente se indique lo contrario.

    Un layout con el nombre de application.rhtml o application.rxml sera configurado como el controlador por defecto si no existe un layout con el mismo nombre que el controlador actual, y no existe un layout asignado explicitamente.

    El layout generado por el script scaffold se ve como esto:

    app\views\layouts\categories.rhtml

    Categories:

    Esto es en su mayoria HTML, mas algunos bits de cdigo Ruby embebido entre etiquetas . Este layout sera llamado por el proceso de renderizado sin considerar la accin que se este ejecutando. Contiene etiquetas estandar HTML las ...... que aparecen en todas las pginas.

    Las partes de Ruby en negrita son traducidas a HTML durante el proceso de renderizado

    Pgina 11

  • de Rails como se muestra a continuacin:

    action_name es un mtodo ActionController que devuelve el nombre de la accin que el controlador esta procesando (ejemplo List) - esto coloca el titulo de la pgina apropiado, dependiendo de la accin que se esta ejecutando.

    Documentacin: ActionController::Base

    stylesheet_link_tag es un helper (ayudante) de Rails una manera perezosa de generar cdigo. Hay muchos de estos ayudantes dentro de Rails. Este simplemente genera el siguiente cdigo HTML:

    Documentacin: ActionView::Helpers::AssetTagHelper

    content_for_layout es la clave de lo que pasa a continuacin. Permite a un unico layout estandar tener contenido dinamico insertado en tiempo de renderizado basado en la accin ejecutada (ejemplo edit, new, list). Este contenido dinamico proviene de un Template (plantilla) con el mismo nombre ver abajo.

    Documentacin: ActionController::Layout::ClassMethods.

    Template (plantilla)

    Convencin de nombres de Rails: las plantillas estan guardadas en app\views\categories\accin.rhtml.

    El nuevo .rhtml creado por el script scaffold es mostrado a continuacin:

    app\views\categories\new.rhtml

    New category

    'create' %>

    'list' %>

    start_form_tag es un ayudante (helper) de Rails para iniciar un formulario HTML aqui genera

    submit_tag por si misma generaria , pero el parmetro Create sobreescribe el valor por defecto Save changes con Create

    end_form_tag solo imprime , no es el helper de Rails mas til creado :- ) pero provee un final satisfactorio para el bloque de cdigo

    Documentacin: ActionView::Helpers::FormTagHelper

    render_partial invocar un Partial (parcial) _form.rhtml vea la siguiente seccin.

    Documentacin: ActionView::Partials

    link_to simplemente crea un link la parte mas fundamental de HTML... Back

    Documentacin: ActionView::Helpers::UrlHelper

    Partial (parcial)

    Convencin de nombres de Rails: un parcial foo estara en el archivo

    Pgina 12

  • app\views\action\_foo.rhtml (note el guion bajo inicial).

    Scaffold u sa el mis mo cdigo para p rocesar a mbas edit y new accines, en tonces coloca el cdigo en un parcial, invocado po r el mtodo render_partial.

    app\views\categories\_form.rhtml

    Category

    Created on

    Updated on

    error_messages_for devuelve una cadena con marca texto para cualquier mensaje de error producido por un intento de enviar el formulario. Si uno o mas errores son detectados, el HTML se vera asi:

    n errors prohibited this xxx from being saved

    There were problems with the following fields:

    field_1 error_message_1 ... ... field_n error_message_n

    Vimos esto en accin en el Da 1 - Ilustracin 2: Capturando errores de datos en la pgina 8 . Nota: las etiquetas css igualan las correspondientes declaraciones en la hoja de estilos creada por el script generar scaffold.

    Documentacin: ActionView::Helpers::ActiveRecordHelper

    text_field es un helper de Rails que genera este HTML: . El primer parmetro es el nombre de la tabla; el segundo es el nombre del campo.

    Documentacin: ActionView::Helpers::FormHelper

    Note u n pequeo bug en Rails sabe como no crear u n cam po de ent rada para los cam pos reservados created_on y u p dated_on, pero aun asi genera las etiquetas para ellos.

    La vista de renderizado para la accin New

    Estamos ya en posicin de mirar el cdigo que devuelve al navegador en respuesta a la accin New, y ver de donde vino todo. El Layout provee el texto en negrita; la plantilla (template) el texto regular; y el parcial el texto en Italica :

    app\views\categories\new.rhtml

    Categories: new

    Pgina 13

  • New category

    Category

    Created on

    Updated on

    Back

    Analizando la vista de la accin List

    Las vistas Edit y Show son si milares a la vista New. List contiene algunos t rucos nuevos. Recuerde como el cont rolador ejecuto la siguien te pieza de cdigo antes de renderiza r la plan tilla List: @category_pages, @categories = paginate :category, :per_page => 10

    paginate p uebla la variable de ins tancia @categories con regist ros or denados de la tabla Categories, :per_page regist ra po r vez, y con tiene toda la lgica para la navegacin a la pgina siguiente / an terior. @category_pages es u na ins tancia a Paginator. Como son usadas en la plantilla se explican al final de la siguiente seccin.

    Documentacin: ActionController::Pagination

    La plantilla se ve como sigue:

    app\views\categories\list.rhtml

    Listing categories

    'show', :id => category %> 'edit', :id => category %> 'destroy', :id => category}, :confirm => "Are you sure?" %>

    Pgina 14

  • @category_pages.current.previous } if @category_pages.current.previous %> @category_pages.current.next } if @category_pages.current.next %>


    'new' %>

    content_columns devuelve un array de objetos columna excluyendo cualquier columna especial (la clave primaria id, todas las columnas que finalizen con _id o _count, y columnas usadas para herencia de tablas)

    Documentacin: ActionController::Base

    human_name es un sinnimo de human_attribute_name, que transforma nombre de atributos claves en un formato leible para el humano, como Primer nombre en vez de primer_nombre

    Documentacin: ActiveRecord::Base

    h automticamente sale del cdigo HTML. Uno de los problemas en permitirle al usuario que ingrese datos que luego son mostrados en la pantalla es que pueden accidentalmente (o maliciosamente) ingresar cdigo que podria romper el sistema cuando es mostrado 4. Para cuidarse contra esto, es buena practica utilizar escape HTML con cualquier dato que es provisto por el usuario. Esto significa que por ejemplo es renderizado como que es inofensivo. Rails hace esto realmente simple solo agrega una h como se muestra.

    confirm es un par metro opcional m uy til para el helper link_to genera una caja emergente de JavaScript que fuer za al usuario a confir mar la accin Destroy an tes de ejecutar el link:

    Documentacin: ActionView::Helpers::UrlHelper

    La lgica de la pgina se aclara un poco. Ruby p uede u tilizar if como m o dificador: expresion if expresion-booleana evalua expresion solo si expresion-boolean es verdadera. @category_pages.current devuelve un objecto Pgina representando la pgina actual.

    ActionController::Pagination::Paginator

    y @category_pages.current.previous devuelve u n nuevo objeto Pgina representado la pgina an terior a la actual, o nulo si esta es la p ri mera pgina.

    ActionController::Pagination::Paginator::Page

    4 Por ejemplo, piense que pasaria si un usuario tipea como una categoria.

    Pgina 15

    Ilustracin 3: Javascript emergente

  • Entonces, si hay u na pgina anterior a la cual navegar, este cont ructor m os t rar u n link; si no hay ninguna, el link es sup ri mido.

    El cdigo generado para la pgina n se vera asi: Previous pageNext page

    Modificar el cdigo generado por ScaffoldEl cdigo generado por el scrip t Scaffold es perfecta men te u sable, y es robusto u na vez que haya agregado suficiente validacin al m o delo de da tos. De todas for mas, si es to fuera todo el desar rollo necesario para aplicacines Rails, entonces los p rogra madores se quedarian sin t rabajo, que claramente no es algo bueno : - ) asi que realize mos algunas m o dificaciones:

    El controlador

    En la vista List, esperaria que los registros sean mostrados en orden alfabtico. Esto requiere un cambio menor al controlador:

    app\controllers\categories_controller.rb (fragmento)

    def list @category_pages, @categories = paginate :category, :per_page => 10, :order_by => 'category'end

    Documentacin: ActionController::Pagination

    En esta aplicacin, la pantalla show es innecesaria todos los campos entran comodamente en una sola linea de la pantalla. Entonces, def show puede desaparecer, y vayamos directamente a la pantalla list despues de un Edit:

    app\controllers\categories_controller.rb (fragmento)

    def update @category = Category.find(@params[:id]) if @category.update_attributes(@params[:category]) flash['notice'] = 'Category was successfully updated.' redirect_to :action => 'list' else render_action 'edit' end end

    El mensaje flash ser tomado y mostrara en la siguiente pantalla en este caso, la pantalla list. Por defecto, el script scaffold no muestra mensajes flash cambiaremos esto en un minuto vea abajo.

    La Vista (View)

    Mostrar mensajes Flash

    Rails p rovee una tcnica para pasar mensajes flash al u suario ejem plo, un mensaje de Actualizacin Exitosa que se m ues t ra en la siguiente pan talla y luego desaparece. Estos p ueden ser to mados fcilmente con u n pequeo cambio al Layout (agregarlo al Layout significa que apareceran en cualquier pan talla):

    app\views\layouts\categories.rhtml

    Categories:

    Pgina 16

  • Documentacin: ActionController::Flash

    Un simple agregado a la hoja de estilo hace que el mensaje flash sea mas visible:

    public\stylesheets\scaffold.css (fragmento)

    .notice { color: red;}

    Compartir variables entre la plantilla y el Layout

    Note que he movido el texto encabezado ... de la plantilla al Layout para que aparezca sobre el mensaje flash. Como cada plantilla tendra un encabezado diferente, necesito colocar el valor de la variable @heading en la plantilla. Rails no tiene problemas con esto variables de plantilla estan disponibles para los Layouts en tiempo de renderizado.

    He realizado este cambio y algunos cambios de formato para terminar mi plantilla:

    app\views\categories\list.rhtml

    Categora Creada Actualizada 'edit', :id => category %> 'destroy', :id => category}, :confirm => "Esta seguro que desea eliminar esta categoria?" %>
    'new' %>1 %>Page:

    No me gusta el formato de la fecha por defecto, entonces uso el mtodo strftime() de Ruby para formatear los campos de fecha y hora a la forma que quiero.

    Ruby Documentacin: class Time

    Pgina 17

  • pgination_links crea una bar ra link HTML bsica para u n paginador dado

    ActionView::Helpers::PaginationHelper

    Atando las pantallas de Edit y New

    Un par de cambios al Parcial utilizado por New y Edit: us una tabla para mejorar el layout; deshacerme de las innecesarias etiquetas created_on/ updated_on; y prevenir que el usuario tipee mucho dentro del campo Category:

    app\views\categories\_form.rhtml

    Category: 20, "maxlength"=>20 %>

    y algunos cambios menores a las dos plantillas (note en particular el uso de @heading)::

    app\views\categories\Edit.rhtml

    'update', :id => @category %> 'list' %>

    app\views\categories\New.rhtml

    'create' %> 'list' %>

    Esto nos lleva al final del Dia 2. Tene mos u n sis te ma funcionando para ma n tener n ues tra tabla de Categorias, y he mos em pezado a to mar cont rol del cdigo scaffold que Rails ha generado.

    Pgina 18

  • Da 3 con RailsAhora es tiempo de empezar con el corazn de la aplicacin. La tabla Items contiene la lista de cosas para hacer. Cada item puede pertenecer a una de las categorias creadas en el Dia 2. Un item opcionalmente puede tener un Nota, guardada en una tabla separada, que veremos maana. Cada tabla tiene una clave primaria id, que tambin es usada para guardar links entre las tablas.

    La tabla Items

    Definicin MySQL de la tabla

    Los cam pos en la tabla Items son los siguientes:

    done 1 significa que el item de la lista ha sido finalizado 5

    priori ty 1 (Alta p rioridad) a 5 (baja p rioridad) descrip tion texto libre indicando cual es la ta rea d ue_date indica cuando se deberia realizar la ta rea category_id un link a la Categoria a la que este item per tenece (id en la tabla de

    Categorias) note_id u n link a una no ta opcional explicando es te item (id en la tabla de no tas) private 1 significa que el ite m de la lista esta clasificado como Privado

    Tabla Items

    CREATE TABLE items ( id smallint(5) unsigned NOT NULL auto_increment, done tinyint(1) unsigned NOT NULL default '0', priority tinyint(1) unsigned NOT NULL default '3', description varchar(40) NOT NULL default '', due_date date default NULL, category_id smallint(5) unsigned NOT NULL default '0', note_id smallint(5) unsigned default NULL, private tinyint(3) unsigned NOT NULL default '0', created_on timestamp(14) NOT NULL, updated_on timestamp(14) NOT NULL, PRIMARY KEY (id)) TYPE=MyISAM COMMENT='List of items to be done';

    El Modelo

    Como an tes, Rails p uede generar u n archivo de m o delo vacio: W:\ToDo>ruby script/generate model item exists app/models/ exists test/unit/ exists test/fixtures/

    5 MySQL no tiene un tipo booleano, entonces usamos 0/1

    Pgina 19

    Ilustracin 4: Modelo de datos simplificado

    Categoriesid

    Notesid

    Itemsidcategory_idnote_id

  • create app/models/item.rb create test/unit/item_test.rb create test/fixtures/items.yml

    W:\ToDo>

    que po de mos poblar con:

    app\models\item.rb

    class Item < ActiveRecord::Base belongs_to :category validates_associated :category validates_format_of :done_before_type_cast, :with => /[01]/, :message=>"must be 0 or 1" validates_inclusion_of :priority, :in=>1..5, :message=>"must be between 1 (high) and 5 (low)" validates_presence_of :description validates_length_of :description, :maximum=>40 validates_format_of :private_before_type_cast, :with => /[01]/, :message=>"must be 0 or 1"end

    Validar los links entre las tablas

    El uso de belongs_to (pertenece a) y validates_associated (validar asociaciones) enlaza la tabla Items con el campo item_id de la tabla Category.

    Documentacin: ActiveRecord::Associations::ClassMethods

    Validar la entrada del usuario

    validates_presence_of proteje los campos NOT NULL contra entradas nulas del usuario

    validates_format_of usa expresiones regulares para chequear el formato de la entrada del usuario

    cuando un usuario tipea una entrada para un campo numrico, Rails siempre la convertira a un nmero si todo falla, un cero. Si desea chequear que el usuario ha realmente tipeado un nmero, entonces necesita validar la entrada con _before_type_cast, que permite acceder la entrada bruta 6.

    validates_inclusion_of chequea la entrada del usuario contra un rango de valores permitidos

    validates_length_of previene que el usuario ingrese datos que serian truncados cuando se almacenen 7.

    Documentacin: ActiveRecord::Validations::ClassMethods

    La tabla de NotasEsta tabla contiene u n solo cam po de texto libre pa ra con tener infor macin fut ura para un item de la lista de tareas en par ticular. Este da to po dria, por sup ues to, haber sido contenido en u n cam po de la tabla Items, de todas for mas, si lo hace de es ta for ma aprendera m ucho mas acerca de Rails : - )

    Definicin de la tabla MySQLTabla Notes

    CREATE TABLE notes (

    6 Lo que pareceria una alternativa mucho mas obvia: validates_inclusion_of :done_before_type_cast, :in=>"0".."1", :message=>"must be between 0 and 1" falla si el campo de entrada queda en blanco

    7 Puede combinar las dos reglas para el campo de Descripcin en una sola: validates_length_of :description, :within => 1..40

    Pgina 20

  • id smallint(6) NOT NULL auto_increment, more_notes text NOT NULL, created_on timestamp(14) NOT NULL, updated_on timestamp(14) NOT NULL, PRIMARY KEY (id)) TYPE=MyISAM COMMENT='Additional optional information for to-dos';

    El modelo

    Genere el archivo de modelos vacio, pero no contiene nada nuevo:

    app\models\note.rb

    class Note < ActiveRecord::Base validates_presence_of :more_notesend

    pero necesita mos recordar agregar este enlace al m o delo de Items :

    app\models\item.rb (fragmento)

    class Item < ActiveRecord::Base belongs_to :note

    Usar un Modelo para mantener Integridad Referencial

    El cdigo que esta mos a p u n to de desar rollar per mitira al u suario agregar una no ta a cualquier Item. Pero que ocurre cuando un usuario borra un Item que tiene un no ta asociada? Clara mente, necesita mos encontrar u na for ma de borrar el regist ro de la Nota ta mbin, de ot ra for ma nos quedan regist ros Notas huerfanos.

    En la for ma de realizar el t rabajo Modelo / Vista / Controlador, es te cdigo per tenece al m o delo. Porqu? Bien, po dra ver m as tar de que pode mos borrar regist ros Items haciendo click en u n cono de papelera de reciclaje en la pan talla lista de tareas, pero ta mbin po de mos borrar u n item haciendo click en Purgar items co m pletados. Colocando el cdigo en el Modelo, sera ejecutado sin tener en cuenta de don de p rovenga la accin de eliminar.

    app\models\item.rb (fragmento)

    def before_destroy unless note_id.nil? Note.find(note_id).destroy end end

    Esto se lee: antes de borrar un registro Item, encontrar el registro en Notas cuyo id sea igual al valor de Nota_id en el registro Item que se esta a punto de eliminar, y eliminarlo primero. A menos que no exista uno :- )

    Similarmente, si un registro es eliminado de la tabla Notas, entonces cualquier referencia a este en la tabla Items necesita ser eliminada:

    app\models\note.rb (fragmento)

    def before_destroy Item.find_by_note_id(id).update_attribute('note_id',NIL) endend

    Documentacin: ActiveRecord::Callbacks

    Pgina 21

  • Mas de ScaffoldGeneremos algo mas de cdigo scaffold. Haremos esto para la tabla Items y la tabla Notas. Todava no estamos listos para trabajar sobre Notas, pero tener en su lugar a scaffold significa que podemos referirnos hoy al cdigo de las Notas sin generar muchos errores. Es como construir una casa scaffold permite contruir una pared a la vez sin que todo se derrumbe alrededor de sus ojos.

    W:\ToDo>ruby script/generate scaffold Item [snip]W:\ToDo>ruby script/generate scaffold Note [snip]W:\ToDo>

    Nota: como m o dificamos la hoja de estilos ayer, ingrese n a la p regunta overwrite (sobreescribir) p ublic / s tylesheets / scaffold.css? [Ynaq].

    Mas acerca de Vistas

    Crear un Layout para la Aplicacin

    Para ahora, se esta volviendo obvio de que todas mis plantillas tendran las mis mas p ri meras lineas de cdigo, entonces tiene sen tido m over el cdigo en co mun a un layout de la aplicacin. Borre todos los archivos app\views\layouts\*.rhtml, y ree m placelos por un archivo com n application.rhtml.

    app\views\layouts\application.rhtml

    El @heading en la plantilla es ahora utilizado para las etiquetas como tambin para . He renombrado public/stylesheets/scaffold.css a todo.css para mantener una prolijidad, y tambin he jugado generalmente con los colores, bordes de las tablas, para

    Pgina 22

  • dar un estilo mas lindo. Tambin he agregado un poco de Javascript para automticamente posicionar el cursor en el primer campo de entrada en el navegador para que el usuario comienze a tipear.

    La pantalla Lista de tareas

    Lo que estoy inten tado conseguir es u na vista basada en un escritorio PalmPilot o PDA si milar. El p rod ucto final es m os t rado en la Ilus tracin 5: La pan talla de Lista de Tareas8.

    Algunos p u n tos:

    haciendo click en el encabezado de la colu mna tilde () eliminara todos los items com pletados. (aquellos marcados con una tilde)

    La pan talla p uede ser ordenada haciendo click en los encabezados de las colu mnas Pri, Descripcin, Finalizar, y Categoria

    los valores 0 / 1 para Ter minado son convertidos en pequeos conos tildes ite ms que pasaron la fecha de finalizacin (due date) son coloreados en rojo y

    m os t rados en negrita la p resencia de u na nota asociada es m os t rada con el cono nota los valores 0 / 1 para Privado son conver tidos en u n s mbolo de candado ite ms individuales p ueden ser edi tados o eliminados haciendo click en los conos de la

    derecha de la pan talla la pan talla tiene un lindo efecto de franjas nuevos items p ueden ser agregados haciendo click en el botn Nueva Tarea... en la

    par te inferior de la pan talla hay un botn enlace a las Categorias del Da 2

    La plantilla u tilizada para obtener esto es la siguiente:

    8 Es asombroso lo que un par de lineas en la hoja de estilos pueden hacer para cambiar la apariencia de la pantalla, por supuesto ademas de la coleccin de conos...

    Pgina 23

    Ilustracin 5: La pantalla de Lista de Tareas

  • app\views\items\list.rhtml

    'new' %> "purge_completed"}, :confirm => "Are you sure you want to permanently delete all completed To Dos?" %> "list_by_priority"}, "alt" => "Sort by Priority" %> "list_by_description"}, "alt" => "Sort by Description" %> "list"}, "alt" => "Sort by Due Date" %> "list_by_category"}, "alt" => "Sort by Category" %> 'button', :onClick=>"parent.location='" + url_for( :controller => 'categories', :action => 'list' ) + "'" } %> { :action => @params["action"] || "index" }) + "" if @item_pages.page_count>1 %>

    Eliminar tareas completadas haciendo click en un cono

    Imagenes clickeables son creadas po r link_to_image, que por defecto espera encont rar la imagen en pub/images con una extensin .png; haciendo click en la imagen ejecutara un m todo especfico.

    Agregando el par metro :confirm genera u na ventana de dialogo emergente javascript como antes

    Documentacin: ActionView::Helpers::UrlHelper

    Haciendo click en OK ejecuta el mtodo purge_completed. Este nuevo mtodo purge_completed necesita ser definido en el controlador:

    app\controllers\items_controller.rb (fragmento)

    def purge_completed Item.destroy_all "done = 1" redirect_to :action => 'list' end

    Item.destroy_all elimina todos los regist ros de la tabla Items don de el valor del cam po id done es 1, y luego devuelve la accin list.

    Documentacin: ActiveRecord::Base

    Cambiar el modo de ordenamiento haciendo click en el Encabezado de la Columna

    Clickeando en el cono de Pri invoca el mtodo list_by_priority. Este nuevo mtodo list_by_priority necesita ser defenido en el controlador:

    app\controllers\items_controller.rb (fragmento)

    def list @item_pages, @items = paginate :item, :per_page => 10, :order_by => 'due_date,priority'

    Pgina 24

  • end def list_by_priority @item_pages, @items = paginate :item, :per_page => 10, :order_by => 'priority,due_date' render_action 'list' end

    Especificamos un modo de ordenamiento por defecto en el mtodo list , y creamos un nuevo mtodo list_by_priority 9. Note tambin que necesitamos explicitamente render_action 'list', por defecto Rails intentar renderizar una plantilla llamada list_by_priority (que no existe :- )

    Agregar el Helper

    Los encabezados para las columnas Nota y Privado son imagenes, pero no son clickeables. He decidido escribir un pequeo mtodo show_image(name) para solo mostrar la imagen:

    app\helpers\application_helper.rb

    module ApplicationHelper def self.append_features(controller) controller.ancestors.include?(ActionController::Base) ? controller.add_template_helper(self) : super end

    def show_image(src) img_options = { "src" => src.include?("/") ? src : "/images/#{src}" } img_options["src"] = img_options["src"] + ".png" unless img_options["src"].include?(".") img_options["border"] = "0" tag("img", img_options) endend

    Una vez que el helper ha sido enlazado por el controlador:

    app\controllers\application.rb

    class ApplicationController < ActionController::Base helper :Applicationend

    esta disponible para todas las plantillas en la aplicacin

    Documentacin: ActionView::Helpers

    Usar botnes de navegacin Javascript

    onClick es u na tcnica s tan dard Javascript para m a nejar accines de bo tnes co mo navegar a una n ueva pgina. De todas for mas, Rails reescribe las di recciones URLs, entonces necesitamos p reguntarle a Rails por la di reccion URL correcta a u tilizar. Dado un controlador y u na accin, url_for devolver la URL.

    Documentacin: ActionController::Base

    Formatear una Tabla con un Parcial

    Queria crear un efecto de franjas para la lista de items. Los Parciales (Partial) proveen la solucin; pueden ser invocados por el mtodo render_partial:

    9 list_by_description y list_by_category son similares y son dejados como un fcil ejercicio para el lector. De todas formas, si queda trabado con list_by_category, vea en la pgina 39

    Pgina 25

  • o por el mas econmico mtodo render_collection_of_partials:render_collection_of_partials "list_stripes", @items

    Documentacin: ActionView::Partials

    Rails tambin pasa un nmero secuencial list_stripes_counter al Parcial. Esta es la clave para el formato alternado de las filas en la tabla con o un fondo gris claro o un fondo gris oscuro. Una forma simple para probar si el contador es impar o par: si es impar, usar el gris claro, si es par, usar el gris oscuro.

    El Parcial completo es como sigue:

    app\views\items\_list_stripes.rhtml

    'items', :action => "edit", :id => list_stripes.id }) %> 'items', :action => "destroy", :id => list_stripes.id }, :confirm => "Are you sure you want to delete this item?") %>

    Un poco de Ruby es usado para probar si el contador es impar o par y renderizar o class=dk_gray o class=lt_gray:list_stripes_counter.modulo(2).nonzero? ? "dk_gray" : "lt_gray"

    el cdigo hasta el signo de iterrogacin pregunta: es el resto cuando se divide list_stripes_counter por 2 es diferente a cero?

    Ruby Documentacin: class Numeric

    El resto de la linea es en realidad una criptica expresin if then else que sacrifica ser legible por ser breve: if la expresin antes de la marca de pregunta es verdadera, devuelve el valor antes de los dos puntos; sino devuelve el valor despus de los dos puntos.

    Ruby Documentacin: Expressions

    Las dos etiquetas dk_gray y lt_gray son definidas en la hoja de estilos:

    public\stylesheets\ToDo.css (fragmento)

    .lt_gray { background-color: #e7e7e7; }

    .dk_gray { background-color: #d6d7d6; }

    Nota: el mismo constructor if then else es usado para mostrar el cono tilde si

    Pgina 26

  • list_stripes["done"]es igual a 1, de otra forma muestra un caracter de espacio en blanco HTML:

    list_stripes["done"] == 1 ? show_image("done_ico") : ""

    Formato basado en el valor de los Datos

    Tambin es fcil resaltar items especficos de da tos por eje m plo, fechas en el pasado. list_stripes["due_date"] < Date.today ? '' : ''

    De nuevo, esto necesita ser igual a la ent rada .past_due en la hoja de estilos.

    Manejar valores perdidos en una busqueda

    Queremos que el sis te ma p ueda cubrirse en la si tuacin don de el u suario borra u na Categoria que esta siendo usada por un item en la Lista de Tareas. En este caso, la Categoria deberia ser m os t rada co mo sin archivar:list_stripes.category ? list_stripes.category["category"] : 'Unfiled'

    OK si ha llegado has ta aqui, deberia tener una pan talla Lista de Tareas que se vea algo como la Ilust racin 5 La pantalla de Lista de Tareas en la pgina 23.

    La pantalla Nueva Tarea

    Ahora sigue que pasa cuando uno p resiona el botn de Nueva Tarea.... De n uevo, todava quedan algunos t rucos en el cdigo.

    La plantilla es mnima:

    app\views\items\new.rhtml

    'create' %> 'button', :onClick=>"parent.location='" + url_for( :action => 'list' ) + "'" } %>

    Pgina 27

    Ilustracin 6 Pantalla Tarea Nueva

  • y el t rabajo real es realizado en el pa rcial, que p uede ser co m par tido con la accin Edit:

    app\views\items\_form.rhtml

    Descripcin: 40, "maxlength" => 40 %> Finalizar: true %> Categoria: Prioridad: Privado? Completado?

    Crear una lista desplegable para el campo fecha

    date_select genera un rudi men tario men u desplegable para ingresar la fecha:date_select "item", "due_date", :use_month_numbers => true

    Documentacin: ActionView::Helpers::DateHelper

    Atrapar excepciones con Ruby

    Desafor tunada men te, date_select feliz mente acep ta fechas co mo 31 de Febrero. Rails m uere cuando inten ta guardar es ta fecha en la base de datos. Una for ma de evitar esto es at rapar este intento de guar dar fallido usan do rescue, u n mtodo de ma nejar excepciones de Ruby

    app\controllers\items_controller.rb (fragmento)

    def create begin @item = Item.new(@params[:item]) if @item.save flash['notice'] = 'Tarea creada exitosamente.' redirect_to :action => 'list_by_priority' else @categories = Category.find_all render_action 'new' end rescue flash['notice'] = 'La tarea no se pudo grabar.' redirect_to :action => 'new' end end

    Ruby Documentacin: Exceptions, Catch, and Throw

    Pgina 28

  • Crear una lista desplegable desde una tabla de busqueda

    Este es ot ro eje m plo de Rails resolviendo u n p roblema de codificacin diario de una for ma extremada mente econ mica. En es te ejem plo:options_from_collection_for_select @categories, "id", "category", @item.category_id

    options_from_collection_for_select lee todos los regist ros en las categorias y los renderiza como [value of category]. El regist ro que es igual a @item_category_id sera etiquetado co mo seleccionado. Si es to no fuera suficiente, el cdigo incluso u tiliza escapes h t ml para los da tos. Habil.

    Documentacin: ActionView::Helpers::FormOptionsHelper

    Note que las cajas desplegables deben t raer los da tos de algun lugar que significa u n agregado al con trolador:

    app\controllers\items_controller.rb (fragmento)

    def new @categories = Category.find_all @item = Item.new end

    def edit @categories = Category.find_all @item = Item.find(@params[:id]) end

    Crear una lista desplegable para la lista de constantes

    Esta es una versin m as sim ple del caso anterior. Agregar u na lista de valores a una caja de seleccin en el cdigo no es siem pre una buena idea es m as fcil cambiar los da tos en la tabla que editar los valores en el cdigo. De todas for mas, hay casos do nde es u na aproximacin perfectamente valida, entonces en Rails haga: select "item","priority",[1,2,3,4,5]

    Note ta mbin como indicar una valor po r defecto en la linea de cdigo anterior.

    Documentacin: ActionView::Helpers::FormOptionsHelper

    Crear una casilla de verificacin

    Otro requeri miento regular; o t ro helper en Rails:check_box "item","private"

    Documentacin: ActionView::Helpers::FormHelper

    Toques finales

    Modificar la hoja de estilos

    Hasta es te p u n to, la pan talla de Lista de Tareas deberia funcionar, y ta mbin deberia funcionar el botn New To Do. Para p roducir las pan tallas m os t radas aqui, ta mbin hice los siguientes cambios a la hoja de es tilos:

    public\stylesheets\ToDo.css

    body { background-color: #c6c3c6; color: #333; }

    .notice { color: red; background-color: white;}

    Pgina 29

  • h1 { font-family: verdana, arial, helvetica, sans-serif; font-size: 14pt; font-weight: bold;}

    table { background-color:#e7e7e7; border: outset 1px; border-collapse: separate; border-spacing: 1px;}

    td { border: inset 1px; }.notice { color: red; background-color: white;}.lt_gray { background-color: #e7e7e7; }.dk_gray { background-color: #d6d7d6; }.hightlight_gray { background-color: #4a9284; }.past_due { color: red }

    La pantalla Editar Tarea

    El res to del Dia 3 es la con tr uccin de la pan talla Editar Tarea, que es m uy si milar a Nueva Tarea. Estaba acos tu mbrado a m olestar me cuando los textos de secundaria decian: esto queda co mo un ejercicio fcil para el lector, ahora es genial po der hacer lo mis mo con us tedes 10.

    Esto nos lleva al final del Dia 3 y ahora la aplicacin no se ve para nada como u n scaffold de Rails, pero bajo la superficie, todava u tiliza mos un gran rango de her ra mientas de Rails pa ra hacer el desar rollo m as fcil.

    10 Pero no como los autores de los textos de secundaria, yo si muestro la respuesta en el Dia 4 :- ) - vea app\views \i tems \edit.rhtml en la pgina 31

    Pgina 30

  • Dia 4 con Rails

    Las pantallas Notas

    Enlazando Notas con Editar Tarea

    Aunque el cdigo scaffold de las Notas le da todas las fcilidades, no queremos que el usuario invoque cualquiera de estas directamente. En cambio, si un item no tiene asociada una nota, queremos poder crear una nota haciendo click en el cono de Nota en la pantalla de Edicion de tareas:

    Si ya existe una nota, queremos poder editarla o borrarla haciendo click en el cono apropiado en la pantalla de Edicion de tareas:

    Primero que nada, veamos el cdigo de la pan talla Editar Tarea. Note como los botnes de Notas cambian de acuerdo a si la Nota existe o no, y co mo el con trol es t ransferido al con trolador de Notas:

    app\views\items\edit.rhtml

    'update', :id => @item %>

    Pgina 31

    Ilustracin 7: Crear una nota nueva desde la pantalla Editar Tarea

    Ilustracin 8: Editar o borrar una nota existente

  • Notes: None "notes", :action => "new", :id => @item.id %> "notes", :action => "edit", :id => @item.note_id %> "notes", :action => "destroy", :id => @item.note_id }, :confirm => "Are you sure you want to delete this note?" %> 'button', :onClick=>"parent.location='" + url_for( :action => 'list' ) + "'" } %>

    La pantalla Editar Notas

    Editar una nota existente es muy simple. Esta es la plantilla:

    app\views\notes\edit.rhtml

    'update', :id => @note %> 'button', :onClick=>"parent.location='" + url_for( :controller => 'items', :action => 'list' ) + "'" } %>

    y el parcial:

    app\views\notes\_form.rhtml

    More notes

    Una vez que la accin update o destroy de la tabla Notas es completada, queremos regresar a la pantalla de Lista de Tareas:

    app\controllers\notes_controller.rb (fragmento)

    def update @note = Note.find(@params[:id]) if @note.update_attributes(@params[:note]) flash['notice'] = 'Note was successfully updated.' redirect_to :controller => 'items', :action => 'list' else render_action 'edit' end end def destroy Note.find(@params[:id]).destroy redirect_to :controller => 'items', :action => 'list' end

    Recuerde las reglas de integridad referencial que ya han sido creadas se aseguraran de

    Pgina 32

  • que cuando u na no ta es eliminada, cualquier referencia a ella sera re movida del Item ta mbin (vea Integridad Referencial en la pgina 21).

    La pantalla de Nota Nueva

    Crear es un poco m as difcil. Quere mos hacer lo siguien te:

    guardar u na n ueva no ta en la tabla de Notas encont rar el id de u n nuevo regist ro creado en la tabla de Notas regist rar es te id en el campo no tes_id del regist ro asociado en la tabla de Items

    Las variables de Sesin nos p roveen una for ma til de m an tener da tos ent re pan tallas po de mos u tilizarlas aqui para guardar el Id del regist ro en la tabla de Notas.

    Documentacin: ActionController::Base

    Guardar y traer Datos usando variables de Sesin

    Primero que nada, cuando creamos un nuevo registro de Nota, pasamos el id del Item que estamos editando:

    app\views\items\edit.rhtml (fragmento)

    "notes", :action => "new", :id => @item.id %>

    El mtodo new en el controlador Notes guarda esto en una variable de sesin :

    app\controllers\notes_controller.rb (fragmento)

    def new @session[:item_id] = @params[:id] @note = Note.new end

    La plantilla Notas Nuevas no tienen sorpresas:

    app\views\notes\new.rhtml

    'create' %> 'button', :onClick=>"parent.location='" + url_for( :controller => 'items', :action => 'list' ) + "'" } %>

    El mtodo create trae los datos de la variable de sesin de nuevo y lo usa para encontrar el registro en la tabla de Items. Luego actualiza el campo note_id en la tabla Item con el id del registro que se acaba de crear en la tabla de Notas, y retorna al controlador Items de nuevo:

    app\controllers\notes_controller.rb (fragmento)

    def create @note = Note.new(@params[:note]) if @note.save flash['notice'] = 'Note was successfully created.' @item = Item.find(@session[:item_id]) @item.update_attribute(:note_id, @note.id) redirect_to :controller => 'items', :action => 'list' else render_action 'new' end end

    Pgina 33

  • Cambiar la pantalla de CategoriasNo hay demasiado por hacer en el sistema ahora, a parte de acomodar las plantillas creadas en los dias anteriores para que tengan el mismo estilo que los botnes de navegacin:

    app\views\categories\list.rhtml

    Category Created Updated 'edit', :id => category.id } %> 'destroy', :id => category.id }, :confirm => 'Are you sure you want to delete this category?' %>

    app\views\categories\new.rhtml

    'create' %>

    app\views\categories\edit.rhtml

    'update', :id => @category %>

    Navegacin a traves del sistemaLos caminos finales de navegacin a t raves del sis tema son m os t rados a continuacin. Cualquier cdigo scaffold redun dan te ejem plo los archivos show.rhtml p uende ser si m plemente eliminados. Esa es la belleza del cdigo scaffold no le cos to ningun esfuerzo crear el cdigo en p ri mer lugar, y u na vez que sirvio su p roposi to, directamente lo p uede eliminar.

    Pgina 34

  • Colocar una pgina de inicio para la AplicacinComo paso final, necesitamos eliminar la pantalla por defecto 'Bienvenido a Rails' si el u suario ingresa en su navegador http://todo. Hay dos pasos:

    Agregar una pgina de inicio al archivo Routes:

    config\routes.rb (fragmento)

    map.connect '', :controller => 'items'

    reno mbrar public\index.html public\index.html.orig

    Descargar una copia de esta aplicacinSi quiere una copia de la aplicacin Lista de Tareas pa ra jugar, hay u n enlace en h t t p: / / r ails.ho melinux.org. Necesita

    usar Rails pa ra ar mar la es t ructura de directorios (vea Rails en la pgina 3) descargar el archivo todo_app.zip en el nuevo directorio creado ToDo desco m pri mir los archivos unzip -o todo_app.zip reno mbrar public\index.html public\index.html.orig si desea u sar la base de da tos de ejem plo, mysql -uroot -p < db/ToDo.sql

    Y finalmenteEspero que encuent re es te docu mento til siem pre me pone conten to recibir comentarios, buenos o m alos, a jp [email protected] .

    Comenta rios de la versin en espaol a em manueln _at_ gmail.com

    Feliz desar rollo con Rails!

    Pgina 35

    Ilustracin 9 Caminos de navegacin a traves de la aplicacin

    ListaTareas

    NuevaTarea

    EditarTarea

    ListaCategorias

    NuevaCategoria

    EditarCategoria

    NuevaNota

    EditarNota

    mailto:[email protected]:[email protected]?subject=Feedback on Four Days on Railshttp://rails.homelinux.org/
  • Apndice Cambios posterioresDespues de escribir Cuatro Dias, recibi m uchos comentarios que ayudaron a mejorar la calidad del docu mento. Una p regunta aparecio repetda mente - como actualizo m as de un regist ro desde la mis ma pan talla - en tonces aqui hay apn dice cubriendo estas Preguntas Frecuentes. No es el concepto mas fcil de do minar, y es u n area que esperaria que aparezcan mas ayudantes (helpers) en el fut uro.

    Actualizaciones MultiplesEn la captura de pantalla de abajo, el usuario puede tildar /des tildar varias Tareas usando las cajas de verificacin en la columna de la izquierda, y luego presionar Guardar para guardar los resultados en la base de datos.

    View

    Rails soporta actualizaciones multiples con otra convencin de nombres, que es agregar el id del registro que se esta editando al nombre entre corchetes [ ]. Esto permite seleccionar un registro en particular desde multiples registros en la pantalla.

    Trabajemos hacia atras desde el HTML que estamos generando. Esto es lo que se ve para el registro con id = 6:

    (checked (seleccionado) es omitido si la casilla de verificacin no esta chequeada)

    Una forma de generar este cdigo es:

    app\view\items\_list_stripes.rhtm (fragmento)

    Pgina 37

    Ilustracin 10 : Actualizaciones multiples

  • Los par metros pa ra check_box_tag son name, value = "1", checked = false, options = {};

    para hidden_field_tag name, value = nil, options = {}

    Documentacin: ActionView::Helpers::FormTagHelper

    Ade mas necesitamos u n bo tn Guardar (Save):

    app\views\items\list.rhtml (fragmento)

    'updater' %>... 'button', :onClick=>"parent.location='" + url_for( :controller => 'items', :action => 'new' ) + "'" } %> 'button', :onClick=>"parent.location='" + url_for( :controller => 'categories', :action => 'list' ) + "'" } %> { :action => @params["action"] || "index" }) + "" if @item_pages.page_count>1 %>

    Controlador

    Lo que re torna del cont rolador cuando se p resiona el botn Guardar es el siguien te hash:params: { :controller=>"items", :item=> { "6"=>{"done"=>"0"}, ... etc... "5"=>{"done"=>"1"} }, :action=>"updater"}

    Estamos interesados en la pa r te de :item. Por ejem plo, la linea en negrita significa el regist ro con el id = 6 tiene el valor del cam po done en 0. Desde aqui, es un t rabajo bas tan te si mple el de actualizar la tabla de Items:

    app\controller\items_controller (fragmento)

    def updater @params[:item].each { |item_id, attr| item = Item.find(item_id) item.update_attribute(:done,attr[:done]) } redirect_to :action => 'list' end

    each coloca 6 en la variable item_id, y done = > 0 en attr.

    Ruby Documentacin: class Array

    Este cdigo funciona, pero si ve que es ta pasan do en development.log, vera que Rails esta t rayendo y actualizando cada regist ro, sea m o dificado o no. No solo esto esta creando actualizaciones innecesarias en la base de da tos, pero ta mbin significa que updated_on ta mbin estan siendo m o dificado, que no es en realidad lo que desea mos. Mucho mejor

    Pgina 38

  • es solo actualizar si done ha cambiado, pero esto significa tener que escribir m as cdigo : - (

    app\controller\items_controller (fragmento)

    def updater @params[:item].each { |item_id, contents| item = Item.find(item_id) if item.done != contents[:done].to_i item.update_attribute(:done,contents[:done]) end } redirect_to :action => 'list' end

    Note que necesita mos conver tir la cadena done a u n en tero usando to_i asi po de mos comparar los valores. Este es el tipo de te ma en el que fcilmente se falla vale la pena chequear development.log de vez en cuando para asegura rse de que Rails esta haciendo lo que u no espera.

    Consideraciones de la interfaz de usuario

    Este cdigo funciona, y p uede ser aplicado para hacer cualquier cam po de la pan talla edi table (otro ejercicio sim ple para el lector : - ). Si p resenta algunas p reguntas interesan tes acerca de que espera el usuario. Que pasa si el usuario cambia algunas de las cajas de verificacin, y luego p resiona Nueva Tarea..., o si re - or dena la pan talla, sin p resionar Guardar? El sis te ma debera siem pre Guardar an tes de realizar cualquier o tra accin? Mas ejercicios para el lector...

    Todava para hacerEn la pgina 25 deje u n ejercicio con list_by_category para el lector. Fue m as fcil de lo que parecia incluso, todavia estoy buscando u na for ma mas elegante en Rails de ordenar po r cam po en u na tabla de busqueda. Ter min con es te hor rible cdigo:

    app\controller\items_controller (fragmento)

    def list_by_category @item_pages = Paginator.new self, Item.count, 10, @params['page'] @items = Item.find_by_sql 'SELECT i.*, c.category FROM categories c, items i ' + 'WHERE ( c.id = i.category_id ) '+ 'ORDER BY c.category ' + 'LIMIT 10 ' + "OFFSET #{@item_pages.current.to_sql[1]}" render_action 'list'end

    Si alguien tiene una mejor solucin, por favor haga melo saber. Dejo este cdigo como ejem plo de que si todo falla, Rails no lo dejara t rabado pero le per mitira ordenar con este viejo cdigo!

    Disfru te el desar rollo con Rails!

    Pgina 39

  • Indice de Terminos de Rails y Ruby usados en este DocumentoAaction_name .......................................................12Bbefore_type_cast ...............................................20belongs_to (pertenece a).................................20Ccheck_box ............................................................29check_box_tag ...................................................38confirm .........................................................15, 24content_columns ..............................................15content_for_layout ...........................................12created_at ..............................................................5created_on ......................................................5, 13current .................................................................15Ddate_select ..........................................................28destroy (destruir) ..............................................10destroy_all ..........................................................24development.log ....................................3, 10, 39Eend_form_tag .....................................................12error_messages_for .........................................13Ffind (encontrar) .................................................10find_all (encontrar todos) ..............................10Flash ......................................................................16Hh .............................................................................15helper (ayudante) ..............................................12hidden_field_tag ...............................................38HTML....................................................................15human_att ribute_name ...................................15human_name .....................................................15Iid ..............................................................................5Integridad Referencial .....................................21LLayout ...................................................................11link_to ..................................................................12link_to_image .....................................................24lock_versin ..........................................................5N

    new (nuevo) ........................................................10Ooptions_from_collection_for_select ............29Ppaginate ...............................................................14pgination_links ...............................................18Partial o Parcial .................................................11previous ...............................................................15Rredirect_to ...........................................................10render_collection_of_partials .......................26render_partial .............................................12, 25render_template ................................................10rescue ...................................................................28Ssave (guardar) ....................................................10select .....................................................................29start_form_tag ...................................................12strftime ................................................................17stylesheet_link_tag ...........................................12submit_tag ..........................................................12TTemplate o Plantilla .........................................11text_field .............................................................13Uupdate_attribute ...............................................38update_attributes (actualizar atributos) . . .10updated_at ............................................................5updated_on ....................................................5, 13url_for ..................................................................25Vvalidates_associated (validar asociaciones) ...20validates_format_of .........................................20validates_inclusion_of .....................................20validates_length_of .....................................7, 20validates_presence_of .....................................20validates_uniqueness_of ...................................7variable de sesin .............................................33..each ......................................................................38

    Pgina 41

    IntroduccinDa 1 con RailsLa aplicacin Lista de TareasEjecutar el script de RailsAgregar la aplicacin al servidor WebDefinir la aplicacin en el archivo de hostsDefinir la aplicacin en el archivo de configuracin de ApacheCambiar a fastcgiChequear que Rails este funcionandoVersiones de RailsConfigurar la Base de DatosCrear la tabla CategoriasDefinicin MySQLModelo de DatosScaffoldRealzar el ModeloCrear reglas de validacin de datosDia 2 con RailsEl cdigo generado ScaffoldEl controladorLa VistaLayoutTemplate (plantilla)Partial (parcial)La vista de renderizado para la accin NewAnalizando la vista de la accin ListModificar el cdigo generado por ScaffoldEl controladorLa Vista (View)Mostrar mensajes FlashCompartir variables entre la plantilla y el LayoutAtando las pantallas de Edit y NewDa 3 con RailsLa tabla ItemsDefinicin MySQL de la tablaEl ModeloValidar los links entre las tablasValidar la entrada del usuarioLa tabla de NotasDefinicin de la tabla MySQLEl modeloUsar un Modelo para mantener Integridad ReferencialMas de ScaffoldMas acerca de VistasCrear un Layout para la AplicacinLa pantalla Lista de tareasEliminar tareas completadas haciendo click en un conoCambiar el modo de ordenamiento haciendo click en el Encabezado de la ColumnaAgregar el HelperUsar botnes de navegacin JavascriptFormatear una Tabla con un ParcialFormato basado en el valor de los DatosManejar valores perdidos en una busqueda La pantalla Nueva TareaCrear una lista desplegable para el campo fechaAtrapar excepciones con RubyCrear una lista desplegable desde una tabla de busquedaCrear una lista desplegable para la lista de constantesCrear una casilla de verificacinToques finalesModificar la hoja de estilosLa pantalla Editar TareaDia 4 con RailsLas pantallas NotasEnlazando Notas con Editar TareaLa pantalla Editar NotasLa pantalla de Nota NuevaGuardar y traer Datos usando variables de SesinCambiar la pantalla de CategoriasNavegacin a traves del sistemaDescargar una copia de esta aplicacinY finalmenteApndice Cambios posterioresActualizaciones MultiplesViewControladorConsideraciones de la interfaz de usuarioTodava para hacer