h1. Taller Rails MyMovil h3. Que vamos a desarrollar * En que consiste la aplicación * Flujo de pantallas. h3. Crear la aplicación Rails * comprobamos que todo está en su sitio * rails, ruby, gem * Escribimos: rails mymovil * explicamos estructura de carpetas * cada cosa en su sitio y un sitio para cada cosa * MVC h3. Configurar Base de Datos * Modificar config/database.yml * poner encoding: utf8 * crear la base de datos ** mysql -u root -p ** create database mymovil_development character set utf8; ** exit *** Por qué usamos utf8 * Ejecutamos rake db:migrate para comprobar que se accede bien * Explicar que es rake. * rake -T. Algunas opciones muy usadas con rake: rake log:clear, rake tmp:clear h3. Describir el modelo de datos * Usuario * Teléfono * Tags h3. Primer modelo: Teléfono * Ejecutar ruby script/generate model Telefono * Explicar lo que crea el generador * Modificar la migración 001 ** numero ** nombre ** descripcion ** ciudad ** pais ** privacidad (_001.txt_) * Ejecutar migración rake db:migrate * Acceder a la BD para comprobar que está creada la tabla Se nos ha olvidado poner que hay ciertas columnas que no pueden ser NULL. Podríamos hacer otra migración, pero como acabamos de empezar, vamos a deshacer la migración y a modificarla y volverla a hacer. * Ejecutamos rake db:migrate VERSION=0 * Modificamos la migración ** añadimos not null en telefono, nombre y provacidad, y por defecto la privacidad es 2 (privado) (_002.txt_) * Mostrar que nos permite hacer nuestro modelo ** demo de ruby script/console * Nociones de Active Record (_004.txt_) ** primer_telefono = Telefono.new(:numero => '666', :nombre => 'Lucifer') ** primer_telefono.pais = 'Infierno' ** primer_telefono.save * Ponemos las validaciones en nuestro modelo: (_003.txt_) h3. Scaffold: Andamios para empezar a construir Los andamiajes (Scaffold) son una estructura que podemos generar con Rails para hacer un mantenimiento básico de los modelos de nuestra aplicación (CRUD: Altas Bajas Modificaciones y Consultas) * Ejecutar ruby /script/generate scaffold Telefono (_005.txt_) * Arrancamos la aplicación con ruby script/server, preferiblemente en otra ventana. (_006.txt_) * Hacer demo del scaffold * Último paso: prueba de las validaciones, para ver mensajes de error ¿Cómo ponemos los mensajes de error en castellano? * Sobreescribimos el método error_messages_for (_007.txt_) * Explicar todo lo que ha creado el scaffold h3. Modificando las vistas Vamos a cambiar el formulario de alta y modificación de teléfonos: * Explicar _form.rhtml y los partials * Modificar el campo privacidad, para hacer una lista desplegable (_008.txt_) * Cambiamos el listado, en el fichero list.rhtml, poner el contenido de (_009.txt_) * Explicar como las vistas se componen "a trozos": layouts, vistas, partials * Ponemos en telefono.rhtml el contenido de _010.txt_ * ponemos el css en public/stylesheets/style.css (_011.txt_) * Enlazamos a la hoja de estilo con: <%= stylesheet_link_tag 'style' %> * Otro ejemplo: <%= image_tag 'miimg.png' %> h4. Metiendo el modelo Usuario Plugins * acts_as_authenticated * se instala con ruby script/plugin install acts_as_authenticated (_012.txt) * Explicar lo que acts_as_authenticated crea ** Modelo ** Sistema de autenticación ** vistas ** Mailer ** Tests Creamos nuestro modelo con: * ruby script/generate authenticated Usuario Cuenta (_013.txt) * crea una migración y todo lo necesario para usarla: librerías, modelo, controlador, vistas * ejecutamos la migración con rake db:migrate * Modificamos controller/application.rb (_014.txt_) Dónde queremos poner la seguridad: * Modificamos nuestro telefonos_controller.rb (_015.txt_) * Explicación de los filtros * Modificamos nuestro layout para tener los logins (_016.txt_) * Explicar: logged_in?, current_usuario * Demo del funcionamiento * Nos damos de alta con un usuario * cuenta_controller.rb no está usando el layout. Se podría añadir otro layout. No nos repetimos. * Mejor tenerlo para toda la aplicación: telefono.rhtml => application.rhtml * Modificar cuenta_controller.rb: ** cambiamos redirect_back_or_default(:controller => '/cuenta', :action => 'index') por redirect_back_or_default(:controller => '/telefonos', :action => 'index') ** Tocamos los mensajes para traducirlos. * Resultado completo en (_017.txt_) h4. Relaciones entre modelos * Un usuario tiene n teléfonos * Un teléfono pertenece a 1 usuario * Relación 1 a n * Necesitamos el campo clave ajena en el modelo * Hacemos una nueva migracion: ruby script/generate migration TelefonoRelacionUsuario * Añadimos la columna a telefonos: (_018.txt_) y al crear el telefono, le añadimos el usuario * En la migración aprovechamos para migrar los teléfonos existentes asignándoles el usuario * Preparamos los modelos: ** belongs_to :usuario (en telefono.rb) ** has_many :telefonos (en usuario.rb) * Ejecutamos rake db:migrate y comprobamos que la migración está hecha * Explicación otras relaciones ActiveRecord: ** has_one ** has_and_belongs_to_many h4. Añadiendo la funcionalidad de telefonos "friend" h5. Seguridad en el acceso público * Acceso al url raiz: todos los telefonos public de todos los usuarios. * Vamos a modificar nuestro controller * tocamos el metodo list (_019.txt_) * Seguimos teniendo que entrar a /telefono. Vamos a cambiarlo * Fichero config/routes.rb. Mapeo de rutas a controladores: * Añadimos la línea: map.connect '', :controller => "telefonos" * Hay que borrar public/index.html para que funcione h5. Acceso a los teléfonos de un usuario * Modificamos el modelo Usuario * Por supuesto con una nueva migración: ruby script/generate migration UsuarioConFriendPassword y el controller para salvar el url_personal y friend_password por defecto al crearlo (_020.txt_) Cómo funciona nuestra aplicación cuando accedemos: * no logado ** / => publicos de todos ** /url => publicos de ese usuario * logado ** / => publicos de todos ** /url => publicos de ese usuario, si es el logado, todos * Tocamos el fichero de rutas, para mapear el url a un parámetro: (021.txt) * De nuevo tocamos el metodo list de telefonos_controller.rb (_022.txt__) Añadimos ahora las cajas para acceso Friend y Private * Añadimos el formulario al principio de telefonos/list.rhtml (_023.txt_) * Tocamos de nuevo el método list para gestionar la password (_024.txt_) h5. Ejercicio * A ver quien descubre un agujero de seguridad de nuestra aplicación (_025.txt_) h4. Modificación del perfil de usuario * Vamos a dejar que cambien su URL personal, con AJAX * creamos la vista cuenta/edit.rhtml (_026.txt_) * tocamos cuenta_controller.rb y añadimos el metodo edit (_027.txt_) * Añadimos <%= javascript_include_tag :defaults %> en nuestro application.rhtml h4. Tags $ ruby script/plugin install acts_as_taggable * Preparamos nuestro modelo: * $ ruby script/generate migration SoporteTags * Editamos la migración para añadir las dos tablas (_028.txt_) * rake db:migrate * añadimos acts_as_taggable en models/telefono.rb * demo de la funcionalidad de tags con la consola (_029.txt_) * Cambiamos el formulario y telefonos_controller.rb (_030.txt_)