sábado, 28 de marzo de 2015

Tutorial Ruby on Rails: Parte IV

​Continuando con el framework Ruby on Rails, ya llego la parte en la que automatizamos tareas y verificamos comportamiento a través del módulo de pruebas de Rails.


Consulta aquí el último commit del proyecto.

1 - Tareas

Hasta ahora he usado rake para operar con la base de datos (rake db:migrate y rake db:rollback) y ver las rutas (rake routes), pero realmente podemos hacer mucho más que eso, ya que rake es una herramienta que maneja tareas y logra automatizar operaciones a través de scripting.

Podemos ver todas operaciones por defecto que nos brinda rails al ejecutar rake -T, pero lo mejor es que podemos crear nuestros propias tareas y estas se encontrarán en la carpeta lib/tasks. Una tarea muy básica luce como el siguiente archivo:

  • La primera línea nos permite describir brevemente nuestra tarea (muy útil al consultar rake -T).
  • En la segunda línea vemos el nombre de la tarea saludar.
  • Dentro de la función lo que vemos es sólo la función puts que imprimirá por consola el mensaje.
Para ver en funcionamiento la tarea ejecutamos rake saludar y veremos que en la consola se imprimirá el mensaje hola hola!.

Pero ahora bien podemos crear una tarea o un grupo de tareas y esto lo logramos con los namespaces, es así como tenemos el grupo de tareas de base de datos con db, documentación con docs, pruebas con test, entre otros. Entonces con esto en mente voy a crear un grupo de tareas con el nombre ejemplos_tareas y dentro de el mostraré las funciones básicas de tareas que existen. Para esto voy a usar el comando rails generate task ejemplos_tareas, con esto se creará el archivo ejemplos_tareas.rake dentro de nuestra carpeta de tareas.

Aquí les comparto el archivo modificado con las tareas que hice:

Las tareas funcionan bajo el namespace de ejemplos_tareas. Por ejemplo para llamar a la tarea 1 ejecutas rake ejemplos_tareas:mi_tarea_1.
  • Tarea 1: Hace uso del parámetro enviroment el cual indica que eres capaz de usar los modelos y funciones que tengas del sistema. Noten la posición de los dos puntos en el nombre de la tarea.
  • Tarea 2: En este caso hago uso de otra sintaxis de enunciar tareas y sólo lo muestro para que tengan la idea de la flexibilidad que tiene Ruby en su sintaxis.
  • Tarea 3: En esta tarea muestro el paso de parámetros y la forma en la que llamamos a esta tarea es rake ejemplos_tareas:mi_tarea_3[42], donde el parámetro es 42.
  • Tarea 4: Hace uso de la función Rake::Task para llamar a otras funciones, la cual permite ejecutar otras tareas dentro de nuestra función.
  • Tarea 5: En este caso hago uso de la sintaxis para llamar a otras tareas como requisito de la tarea 5, esto quiere decir que se ejecutará las tareas requisito antes de la tarea 5, por lo que se tendrá como salida:
    hola
    hola 2
    hola 3
  • Tarea 6: Aquí hago uso de la variable enviroment para poder acceder al modelo Post y dentro de la función me encargo de imprimir un mensaje con el nombre de un Post seleccionado al azar.
Ahora podemos consultar las tareas que tenemos de nuestro grupo ejemplos_tareas con el comando rake -T ejemplos_tareas y la salida que veremos lucirá como la siguiente imagen:


Ya con esto tenemos la idea de como podemos hacer tareas más complejas como generar reportes, asignar al sistema una actualización de datos cada cierto tiempo, hacer respaldos, entre otros.

Puedes consultar la documentación oficial y este otro tutorial que veo muy interesante por si desean aprender mucho más sobre rake.

2 - Introducción a las pruebas

El archivo principal es test/test_helper.rb, este tiene la capacidad de conectarse con las librerías y fixtures (casos de prueba para un modelo), de forma tal que los otros módulos de prueba lo pueden importar y hacer uso de todas sus funciones. Es por esto que incluyo la instrucción include Devise::TestHelpers dentro de este archivo para notificarle al módulo de pruebas de uso de Devise (librería de manejo de usuarios). Además tengo que modificar el fixture del modelo User para tener instancias de prueba.

A partir de este momento podemos empezar a realizar pruebas a nuestros modelos, controladores, integración, mailers y jobs. Ejecutar una prueba lo logramos con nuestra herramienta rake y podemos usar la tarea que prueba todos controladores con el comando rake test:controllers y obtendremos una salida como esta:

.
Finished tests in 0.006932s, 104.420 tests/s, 104.420 assertions/s.
10 tests, 10 assertions, 0 failures, 0 errors, 0 skips


Lo cual significa que se realizaron 10 pruebas y 10 éxitos, que vienen de las pruebas especificadas en los archivos de la carpeta test/controllers que se crearon automáticamente al haber usado Scaffold. En caso de tener errores y fallas se verán en la primera línea del reporte una o más E y F respectivamente. Revisemos entonces el archivo test/controllers/posts_controller_test.rb.

Notemos primeramente que al declarar una prueba la sintaxis de la función es test "should get index" do esto equivale a def test_should_get_index. Ahora bien dentro de las pruebas notemos que usan las funciones assert, estas se aseguran de que se cumplan una condición para determinar el resultado de la prueba y para esto contamos con una gran cantidad de variantes de la función que pueden consultar en la página oficial de Rails.

En detalle las pruebas anteriormente especificadas significan que se cumpla una propiedad, por ejemplo:
  • should get index: Busca obtener el listado de Post, compara con el valor de éxito y chequea que se instancie la variable posts.
  • should get new: Crea una instancia del modelo Post y compara con el valor de éxito.
  • should create post: Verifica que si sea creado el Post, tomando el número de instancias del antes y después. La prueba finaliza con asegurarse del redireccionamiento a la muestra del Post.
  • should show post y should get edit: Buscan asegurarse que se tome Post según el id.
  • should update post: Se verifica la actualización del Post. La prueba finaliza con asegurarse del redireccionamiento a la muestra del Post.
  • should destroy post: Se verifica que el Post sea eliminado, comparando el número de instancias del antes y después.
Podemos realizar también pruebas puntuales, por ejemplo si se quisiera probar únicamente "should get index" dentro de este controlador, ejecutamos rake test test/controllers/posts_controller_test.rb test_should_get_index.

Una buena práctica que podemos adoptar al desarrollar es chequear el estatus de nuestras pruebas con un script antes de subir los cambios al repositorio o colocar en producción el sistema.

Para conocer más sobre el módulo de pruebas puedes consultar la documentación oficial. Existen también herramientas como Capybara que buscan facilitar la realización de pruebas.

Si algo no queda muy claro siempre me pueden escribir a mi correo tonylattke@gmail.com o también pueden dejar comentarios al final de este post y trataré de ayudarles lo antes posible.

Accede al repositorio del proyecto aquí.

sábado, 21 de marzo de 2015

Tutorial Ruby on Rails: Parte III


​En este tutorial continuaré con el framework Ruby on Rails. Ya llevamos recorrido con la parte I y la parte II:
  • Crear un proyecto.
  • Trabajar con controladores.
  • Agregar un modelo.
  • Uso de la plantilla.
  • Usar la herramienta Scaffold.
  • Migraciones.
  • Consultas a base de datos.
  • Manejo de sesión.

Consulta aquí el último commit del proyecto.

Nota: Se asume que ya se tiene al menos un usuario registrado en la aplicación.

1 - Herramienta de administración

Para contar con una herramienta de administración vamos a nuestro Gemfile y agregamos gem 'rails_admin', :git => 'git://github.com/sferik/rails_admin.git'. En caso de que estén trabajando con Ruby versión 1.8 o menor agreguen esta gema también gem 'fastercsv'.

Luego instalamos las nuevas dependencias bundle install, generamos rails generate rails_admin:install (automáticamente tendremos la ruta al admin agregada) y migramos rake db:migrate.

Ya con esto podemos visitar nuestra herramienta accediendo a localhost:3000/admin y veremos la siguiente pantalla:


Con esta herramienta ya somos capaces de brindar servicios de administración para el manejo de nuestros de datos a través de una interfaz muy amigable.

Con un admin podemos acceder a nuestras tablas de la base de datos y hacer todas las operaciones de costumbre (crear, actualizar, eliminar, entre otras), pero lo más importante es que podemos corregir errores rápidamente, porque al hacer pruebas y casos bordes que no hemos visto, son comúnmente situaciones que tenemos que enfrentar.

Ahora bien ¿a esta poderosa herramienta debe acceder todo usuario? por supuesto que no, así que vamos agregar permisos. Primero vamos agregar que sólo puede acceder un usuario que haya iniciado sesión, eso lo logramos descomentando en el archivo /config/initializers/rails_admin.rb las líneas que tienen el código sobre devise.

Ok ahora sólo los usuarios que tengan una sesión iniciada podrán acceder al admin, pero no es suficiente todavía, porque por ahora se registra cualquier persona muy fácilmente con su correo y una contraseña, así que agreguemos un atributo que indique si el usuario es o no administrador.
  • Primero agregamos la gema cancan a nuestro Gemfile, luego lo instalamos con bundle install y generamos el modelo ability con el comando rails generate cancan:ability.
  • Modificamos el archivo /app/models/ability.rb para que luzca como el siguiente:
  • Luego descomentamos la línea de código que refiere a Cancan en el archivo config/initializers/rails_admin.rb.
  • Agregamos a nuestros usuarios el atributo admin, para eso creamos la migración con rails g migration AgregarAdminAUsuario y dentro de la función change agregamos add_column :users, :admin, :boolean, :default => false. Una vez que tengamos esto migramos rake db:migrate.
  • El siguiente paso es crear la función en el modelo de usuario para saber si es o no administrador, para eso modificamos el archivo /app/models/user.rb agregando la función def admin?. El archivo luce al final de esta forma:
En este momento todo funciona y verás que no existe forma de acceder al admin, ya que todos los usuarios que tengas hasta ahora por defecto no son administradores, es por eso que debemos ahora asignarle a uno de los usuarios que tengamos el valor de verdadero en el attributo admin. Una manera es que comentemos en el ability.rb la función if, accedemos a nuestro admin y le asignamos verdadero al atributo en el usuario que deseamos. Otra forma es acceder a la consola de rails y ejecutemos los comandos:
  • user = User.find(1) busca el usuario con id 1.
  • user.update_attribute(:admin, true) a es usuario actualizamos el atributo admin.
Nota: Esta no es la única herramienta de administración, existen otras que pueden conseguir si investigan. Mi objetivo con este punto es mostrar una de las herramienta disponibles de administración.

Consulta aquí el commit del proyecto donde se agrega el admin y este otro commit donde cambio los permisos.

2 - Active Records

Estas son las herramientas que nos facilitan a la creación y uso de nuestro modelo. Así que esta parte ya la conocemos medianamente, porque es la que llamé en la parte II consulta a la base de datos. Pero ahora bien podemos estudiar un poco más los modelos que tengamos y ver que cosas interesantes extras podemos hacer.

Por ejemplo si queremos modificar el nombre de la tabla, usamos para eso dentro de nuestro modelo la variable self.table_name y le asignamos otro valor.

Otro caso que puede llegar a surgir es cambiar la clave del modelo y eso lo logramos con la variable self.primary_key.

Algo que ya hicimos fue agregar una función para determinar el valor del atributo admin en el modelo usuario.

También podemos decirle a nuestro modelo si pertenece o tiene referencias a otros modelos y lo logramos con:
  • has_many :comentarios puede servir en el caso de indicar que modelo post tiene comentarios.
  • belongs_to :post este en caso contrario, un comentario pertenece a un post.
Sin embargo la función que posiblemente nos interese especialmente es la validación de atributos, por ejemplo dentro de un formulario que tenga un atributo como requisito: el valor debe ser asignado. Esto lo logramos con esta expresión validates :nombre_atributo, presence: true.

Para más información sobre este punto puedes consultar la documentación oficial.

3 - Active Support

Es el componente que nos permite proveer a Rails todo el poder de Ruby. Esto lo logra a través de las extensiones que tenemos de:
Para más información sobre este punto puedes consultar la documentación oficial.

4 - Estilo y archivos estáticos

Para modificar un poco la apariencia vamos a cambiar el archivo de plantilla /app/views/layouts/application.html.erb y que luzca como sigue:

Los cambios realizados son:
  • Agregue la barra de navegación.
  • Agregue las instrucciones para linkear las librerías de Jquery y Bootstrap.
Ahora si vamos a agregar los archivos a sus carpetas correspondientes en la carpeta /app/assets.
  • javascripts: bootstrap.js y jquery-1.10.2.js.
  • stylesheets: bootstrap.css y bootstrap.min.css (realmente sólo hace falta uno de estos pero los dejé para modificaciones a futuro).
  • fonts: Para hacer las cosas más interesantes, cree la carpeta fonts, para mostrar la posibilidad de seguir agregando contenido, ya que pudiésemos en un futuro cargar archivos de texto plano, fotos, pdf, zips, entre otros. Para divertirnos un poco más con Bootstrap, incluyo la fuente glyphicons-halflings-regular en sus distintos formatos: eot, svg, ttf y woff.
Para acceder a todos estos archivos puedes descargarlos aquí.

Lo siguiente que tenemos que hacer es avisar a Rails que tiene que encontrar esos archivos y lo logramos creando dentro de la carpeta /config/initializers/ el archivo assets.rb, con la siguiente información:

Ya de esta forma tenemos nuestra aplicación al tanto de esos archivos y podemos visitar la página de inicio con la siguiente nueva apariencia:


Consulta aquí el commit con los cambios realizados.

Hasta este punto conocemos lo básico de Rails, pero les aseguro que pueden hacer con esta información un blog parecido a este proyecto que hice: Blog con Rails. Más cosas cheveres que hacer con Rails por supuesto que quedan, pero depende mucho de cada proyecto, ya que pudiésemos querer conectarnos con alguna red social, uso de una librería o gema específica, configuraciones con una plataforma como Heroku... Así que de esta forma lo que nos quedaría pendiente en teoría es hacer uso de tareas y pruebas en Rails.

Si algo no queda muy claro siempre me pueden escribir a mi correo tonylattke@gmail.com o también pueden dejar comentarios al final de este post y trataré de ayudarles lo antes posible.

Accede al repositorio del proyecto aquí.

sábado, 14 de marzo de 2015

Tutorial Ruby on Rails: Parte II


​En este tutorial continuaré con el framework Ruby on Rails. Si recordamos del post anterior ya aprendimos:
  • Crear un proyecto.
  • Trabajar con controladores.
  • Agregar un modelo.
  • Conocimos la existencia de la plantilla para las vistas.
  • Usar la herramienta Scaffold.

Ya para este tutorial continuaré a partir de ese punto en el que me quede. Consulta aquí el último commit del proyecto.

1 - Migraciones

Es un sistema que nos permite evolucionar nuestro esquema de la base de datos mientras desarrollamos nuestra aplicación. Este sistema nos permite hacer los cambios en la base de datos sin tener que usar código SQL directamente.

En este caso deseamos agregar a nuestros posts el nombre del autor, esto lo logramos modificando el modelo a través de una migración.

Para crear una migración usamos el comando rails generate migration AgregarAutorAPost donde AgregarAutorAPost es el nombre de la migración, el cual describe de una forma muy breve el cambio que deseamos realizar. Este comando creará un archivo dentro de la carpeta db/migrate y el archivo se llamó en mi caso 20150314102224_agregar_autor_a_post.rb, este nombre viene compuesto de la fecha, hora y nombre de la migración. Para poder agregar este atributo autor dentro de la tabla posts lo que hacemos es agregar dentro de la función change la instrucción add_column :posts, :autor, :string, :default => "Tony", esta no solo agregará el atributo sino que también le dará como valor por defecto de autor Tony. El archivo terminará viendo de la siguiente forma:

Antes de ejecutar los cambios en la base de datos crearé otra migración, para hacer el ejemplo más interesante y lo que haré es cambiar el tipo del atributo de contenido dentro de post. El atributo pasará de ser tipo string a tipo text, ya que dentro de un post me interesa un contenido escrito con párrafos y valor de gran tamaño. Creamos la migración:

rails generate migration CambiarTipoContenidoPost

Y dentro de la función change agregamos la instrucción change_column :posts, :contenido, :text, :limit => 4294967296. Esto significa exactamente lo que queremos y además le agrego el atributo limit en la función con valor 4294967296 (valor máximo de un atributo tipo text por defecto), ya que de no hacerlo el atributo tendría un limite de 255 caracteres por tratarse de un cambio de tipo.

El archivo de migración terminará viendo de la siguiente forma:

Ahora si, para hacer todos los cambios en la base de datos ejecutamos rake db:migrate. Pero que va a pasar ahora, las vistas, controlador y archivos que manejan las pruebas, no están al tanto de los cambios y es por eso que necesitamos hacer los cambios en los siguientes archivos, para garantizar la integridad del sistema:
  • app/controllers/posts_controller.rb
  • app/views/posts/_form.html.erb
  • app/views/posts/index.html.erb
  • app/views/posts/index.json.jbuilder
  • app/views/posts/show.html.erb
  • app/views/posts/show.json.jbuilder
  • test/controllers/posts_controller_test.rb
  • test/fixtures/posts.yml
Commit hasta este punto del proyecto para ver los cambios. Cambio dentro del archivo del controlador faltó por error mío, aquí esta el commit en cualquier caso que lo necesiten.

Además de las operaciones sobre migraciones que mostré, pueden hacer todas estas otras (Rails versión 4.1.1).
  • add_index: Agregar índice a un atributo en la tabla.
    Ejemplo: add_index :nombre_tabla, :nombre_atributo
  • add_reference: Agrega en una tabla un atributo con referencia a otra tabla.
    Ejemplo: add_reference :nombre_tabla, :nombre_tabla_referenciada, index: true
  • add_timestamps: Agrega los atributos que indican momento de creación y modificación.
  • add_foreign_key: Agrega una clave foránea para garantizar integridad.
    Ejemplo: add_foreign_key :nombre_tabla :nombre_tabla_referenciada
  • create_table: Permite crear una tabla.
    Ejemplo siendo posts la tabla creada con los atributos nombre y contenido:
    create_table :posts do |t|
    t.string :nombre
    t.text :contenido
    end
  • create_join_table: Crea una tabla que representa la unión de otras 2 a partir de sus identificadores.
    Ejemplo:create_join_table :tabla_1, :tabla_2, table_name: :nombre_tabla_nueva
  • drop_table: Elimina una tabla.
    Ejemplo: drop_table :nombre_tabla
  • drop_join_table: Elimina tablas unidas que fueron creadas con create_join_table. Si le dimos un nombre podemos usar simplemente el comando drop_table.
    Ejemplo: create_join_table :tabla_1, :tabla_2
  • remove_timestamps: Permite eliminar los atributos de tiempo en la tabla.
    Ejemplo:remove_timestamps :nombre_tabla
  • remove_reference: Elimina referencia de tabla.
    Ejemplo:remove_reference :nombre_tabla, :nombre_tabla_referenciada
  • rename_table: Permite darle un nuevo nombre a la tabla.
    Ejemplo:rename_table :actual_nombre_tabla :nuevo_nombre_tabla
  • rename_column: Le da un nuevo nombre a un atributo en tabla especificada.
    Ejemplo:rename_colum :nombre_tabla :actual_nombre_atributo :nuevo_nombre_atributo
  • rename_index: Permite darle un nuevo nombre al índice en la tabla.
    Ejemplo:rename_index :nombre_tabla :actual_nombre_indice :nuevo_nombre_indice
Para saber más sobre migraciones consulta la documentación oficial.

2 - Operaciones en base de datos

Esta sección más que un ejemplo, será para explicar las funciones que tenemos para interactuar con la base de datos, ya que al haber usado Scaffold gran parte del trabajo ya esta realizado. Entonces si revisamos el controlador de posts, podemos ver todas las funciones.

  • Post.all: Seleccionamos todos las instancias de Post (ejemplo en la línea 7).
  • Post.new: Crea la instancia de Post sin valores y todavia no se ha guardado (ejemplo en la línea 17).
  • Post.new(post_params): Esto significa que se crea la instancia con lo que este en el diccionario de datos en la variable post_params (ejemplo en la línea 27). En este caso el sistema esta tomando los valores que introdujo el usuario, pero si queremos crear uno nosotros mismos, este debe tener la forma post_params = {'nombre' => 'Hola mundo', 'contenido' => 'Funciona', 'autor' => 'Tony'}.
  • post.save: Este indica que la instancia que se almacena en la base de datos (ejemplo en la línea 30).
  • Post.find(1): Esta función devuelve la instancia de Post con id 1.
  • Post.find_by(params): Permite buscar instancias Post por otros atributos, por ejemplo params puede tener el valor {'nombre' => 'Hola Rails'}, lo cual significa buscar por nombre.
  • post.update(post_params): Podemos actualizar la instancia actual con los valores en los atributos que tengamos en la variable post_params (ejemplo en la línea 44).
  • post.update_attribute(:nombre, "Hola mundo Rails"): Permite actualizar el atributo nombre de la instancia actual.
  • post.destroy: Permite remover la instancia de la base de datos (ejemplo en la línea 57).
Dentro de este archivo notamos que existen variables con un @ que le precede, esto significa que la variable se comunica con la vista. Quiero que también noten que al referirme a la clase Post escribo con mayúscula la primera letra, pero al referirme a una instancia que tengo en una variable, siempre escribo post.

Puedes ver la documentación oficial sobre consultas para mayor información.

3 - Manejo de sesión

Para tener usuarios en el sistema vamos a usar la librería o gema devise y lo primero que hacemos es agregar en el archivo Gemfile esta instrucción gem 'devise'. Luego le le decimos al sistema que instale todas las gemas con el comando bundle install.

Ahora generamos los archivos de configuración dentro del sistema con el comando rails generate devise:install, luego generamos el modelo con rails generate devise user, seguidamente generamos las vistas con rails generate devise:views.

Ejecutamos rake db:migrate para reflejar la migración y tener la base de datos con la tabla de usuarios.

Y por último agregamos al archivo config/environments/development.rb la instrucción config.action_mailer.default_url_options = { :host => 'localhost:3000' }, ya que nos encontramos en desarrollo y el sistema de usuarios necesita que se especifique esto.

Ya con esto podemos visitar el links de registro localhost:3000/users/sign_up y veremos la siguiente pantalla:


Llenamos nuestros datos y presionamos Sign up, con esto veremos la pantalla inicial, pero ¿cómo cerramos sesión? modificamos la vista de la plantilla para que luzca como el siguiente archivo:

Los cambios realizados son:
  • Cambie la forma de usar Bootstrap, con las líneas 8 a la 15 y 28. Con esto accedemos a los archivos de Bootstrap de forma local (aunque los archivos no están cargados todavía).
  • Con las líneas 19 y 20 agregamos mensajes de operaciones realizadas y de alertas.
  • Con las líneas 21 a la 25 podemos ver los links de iniciar y cerrar sesión, dependiendo del estado actual.
Ahora podemos cerrar sesión y acceder al botón de iniciarla, con esto tendremos la siguiente vista:


Consulta aquí el commit hasta este punto del proyecto.

Ya en la próxima parte de este tutorial trataré la gema de administrador, los Active Record y Active Support, ya que en los últimos días he estado leyendo que son requisitos para trabajos.

Si algo no queda muy claro siempre me pueden escribir a mi correo tonylattke@gmail.com o también pueden dejar comentarios al final de este post y trataré de ayudarles lo antes posible.

Accede al repositorio del proyecto aquí.

sábado, 7 de marzo de 2015

Tutorial Ruby on Rails: Parte I


​En este tutorial empezaré con el framework Ruby on Rails y como ya habia mencionado en el post anterior se trata de un framework escrito en Ruby y por tanto recomiendo conocer un poco el lenguaje para saber hacer funciones básicas. Puedes visitar mi repositorio sobre Ruby para encontrar algunas de las operaciones básicas del lenguaje.


Comandos para instalar Ruby on rails en Linux:
​ A lo largo del tutorial voy a dejarles los links de los commits que realice, para que vean con exactitud en caso de dudas los cambios realizados en el proyecto.

1 - Crear el proyecto

Primero que nada nos posicionamos en la carpeta en la que deseamos trabajar nuestro proyecto y luego ejecutamos el comando rails new blog, este creará un proyecto con el nombre blog y dentro de la carpeta encontrarás muchos archivos y carpetas:


Una breve descripción de las carpetas a continuación:
  • app: En esta se encuentran todos los assets (Javascript, CSS e imágenes), controladores, helpers (servicios de ayuda), mailers (te permiten enviar Emails), modelos y vistas.
  • bin: Contiene los scripts que permiten correr la aplicación.
  • config: Los archivos de configuración. Los archivos de principal interés aquí son los de la base de datos y rutas.
  • db: Tiene el esquema de la base de datos y migraciones.
  • lib: Aquí colocaremos las librerías y las tareas que no corresponden a los controladores, por ejemplo podemos dejar programas que necesitamos que el servidor ejecute a cada hora.
  • log: Al momento de depurar la aplicación, podremos ver un registro de errores en esta carpeta.
  • public: En esta carpeta encontraremos los HTML que atajan los errores 404 (contenido no encontrado), 422 (error de procesamiento de la consulta) y 500 (error en el servidor). Además hospedamos en esta carpeta los archivos subidos al servidor por el usuario, como por ejemplo una foto de perfil.
  • test: Archivos necesarios para las pruebas.
  • tmp: Archivos temporales.
  • vendor: Esta carpeta es similar a lib, pero en esta colocarás como buena práctica el contenido de librerías que haz descargado.
Los archivos:
  • config.ru: Es el archivo que usa el servidor para correr la aplicación.
  • Gemfile: Corresponde a la lista de librerías o gemas que necesita la aplicación.
  • Gemfile.lock: Se trata de un archivo que se auto modifica según el Gemfile y la idea principal de este es tener todas las dependencias calculadas al momento de implementar.
  • Rackfile: En este archivo es donde indicamos la conexión con los programas de tareas en la carpeta lib.
  • README.rdoc: Es una breve descripción de tu aplicación.
Y la carpeta en la que más nos concentramos en el proyecto es la carpeta app.

  • assets: Carpeta que tiene todos los Javascript, CSS e imágenes.
  • controllers: Controladores de la aplicación.
  • helpers: Funciones, variables y estructuras de ayuda que tenemos para cada controlador.
  • mailers: Contiene los archivos para manejar el envío de correos desde la aplicación.
  • models: Son los archivos que corresponden a los modelos del sistema, ellos están directamente relacionados con el esquema de la base de datos.
  • views: Contiene las vistas.
Finalmente para terminar esta sección, hacemos correr nuestro servidor ejecutando rails s​erver o rails s. Veremos una página como esta al visitar la dirección localhost:3000.


Consulta aquí el commit hasta este punto del proyecto.

2 - Agregando controlador

Un controlador es el que permite conectar los modelos, operaciones sobre ellos y las vistas.

Para crear un controlador usamos este comando rails generate controller bienvenido el cual se llamará bienvenido. Al haber hecho esto tendremos los siguientes archivos creados en el proyecto:
  • app/controllers/bienvenido_controller.rb: Es el archivo principal donde manejamos cada función relacionada con las vistas de este controlador.
  • app/views/bienvenido: Es la carpeta creada para las vistas de este controlador.
  • test/controllers/bienvenido_controller_test.rb: Archivo para manejar las pruebas a nivel del controlador.
  • app/helpers/bienvenido_helper.rb: Módulo que tiene las funciones de ayuda para este controlador.
  • test/helpers/bienvenido_helper_test.rb: Archivo para manejar las pruebas sobre las funciones de ayuda en el controlador.
  • app/assets/javascripts/bienvenido.js.coffee: Javascript para este controlador basado en la sintaxis que nos da la herramienta CoffeeScript.
  • app/assets/stylesheets/bienvenido.css.scss: CSS para este controlador usando la herramienta SASS.
Ahora podemos crear nuestra primera vista en el controlador con un archivo dentro de la carpeta /app/views/bienvenido y el archivo lo llamaré index.html.erb, donde la extensión html.erb significa que es un HTML enriquecido con código en Ruby. Y el contenido de este archivo es este: <h1>Mi Blog</h1>

Para indicarle al controlador que tenemos esta vista creamos un método llamado de igual forma que el archivo HTML index.

Ahora para lograr tener acceso a esta vista finalmente agregamos en el archivo de rutas /config/routes.rb la instrucción get 'bienvenido/index', aunque con esta veremos la página con el link localhost:3000/bienvenido/index. Por esto usaré mejor esta instrucción root 'bienvenido#index' ya que se trata de una página principal y de esta forma reemplazo la vista que tenía en la dirección localhost:3000 y tendré la siguiente página:


Consulta aquí el commit hasta este punto del proyecto.

3 - Agregar modelo

Para hacer esto ejecutamos el comando rails generate model Post nombre:string contenido:string, este creará el modelo Post con los atributos nombre y contenido como strings. Los otros tipos de atributos que podemos crear son: binary, boolean, date, datetime, decimal, float, integer, string, text, time, timestamp. Además podemos indicar que el atributo hace referencia a otro modelo con reference o podemos cambiar el identificador con primary_key.

Los archivos creados por el comando fueron:
  • db/migrate/20150307101204_create_posts.rb: Indica a la base de datos la migración con la nueva tabla posts.
  • app/models/post.rb: Corresponde al modelo en el proyecto.
  • test/models/post_test.rb: Archivo para especificar las pruebas en el modelo.
  • test/fixtures/posts.yml: Contiene la especificación de las instancias de prueba para este modelo.
Pero en este momento la base de datos no conoce todavía la tabla de posts y para lograrlo ejecutamos rake db:migrate.

4 - Rutas

En esta sección agregaremos el modelo a las rutas y lo único que tenemos que hacer es agregar la instrucción resources :posts dentro de config/routes.rb. Ahora podremos ver todas las rutas del sistema usando el comando rake routes.


Aunque en este tutorial quiero mostrar únicamente los posts en la página principal y esto lo hago agregando dentro del controlador bienvenido en el método index la instrucción @posts = Post.all.

​​Y para lograr ver los elementos en pantalla de bienvenida, modificamos el HTML como se ve en el siguiente archivo:


Este código luce muy parecido a los HTML que conocemos pero con las etiquetas especiales <% y %> que permiten agregar código Ruby. En el archivo tenemos la sintaxis de las funciones if y each. Podemos darnos cuenta que con la instrucción de la línea 8 se está logrando imprimir contenido en el HTML y esto es gracias al símbolo = dentro de la etiqueta.

Ahora podemos visitar la página principal, esta nos dirá que no tenemos ningún posts y con esto ya confirmamos que vamos bien hasta aquí. En vez de crear una vista para agregar una instancia voy a utilizar la consola del proyecto con el comando rails c, que me permite interactuar con el proyecto.

Ahora para crear una instancia lo que hago es escribir post = Post.new({:nombre => 'Hola mundo', :contenido => 'funciona'}) y luego post.save, esto nos creará una instancia y guardará en la base de datos. Lo que veremos en pantalla será esto:


Y al consultar nuestra página en el navegador veremos la siguiente página:


5 - Plantilla del HTML

Todas las páginas páginas están usando hasta ahora si nos fijamos los mismos HTMLs, Javascripts y hojas de estilo como base y eso es gracias a la plantilla que tenemos en el archivo app/views/layouts/application.html.erb, así que para ir mejorando la apariencia del proyecto voy agregarle al viejo amigo Bootstrap con un link desde la librería Online.


Consulta aquí el commit hasta este punto del proyecto.

6 - Usando Scaffold

Pudiese crear todas las vistas para cada función en el modelo Post si siguiese todos los pasos que normalmente aconsejan en la documentación oficial, pero prefiero mostrarles otra herramienta increíble Scaffold, aunque antes de eso les muestro como podemos eliminar un modelo del sistema. Para hacer esto último, le decimos a la base de datos que queremos eliminar la tabla y se logra simplemente deshaciendo la migración con el comando rake db:rollback. Luego ejecutamos el comando rails destroy model Post y con esto ya eliminamos los rastros del modelo en el proyecto.

Ahora si estamos listos para poder usar Scaffold. Esta herramienta permite crear el modelo, controlador y vistas en un único comando rails generate scaffold Post nombre:string contenido:string. A diferencia de lo que se creaba con el comando que generaba modelos y controladores tenemos estos archivos extras:
  • app/views/posts/index.html.erb: Muestra la lista de posts.
  • app/views/posts/edit.html.erb: Permite editar un post.
  • app/views/posts/show.html.erb: Muestra un post.
  • app/views/posts/new.html.erb: Esta vista permite crear un post.
  • app/views/posts/_form.html.erb: Aquí tenemos el formulario para crear y editar el post.
  • app/views/posts/index.json.jbuilder: Vista que maneja la salida de todos los posts en formato json.
  • app/views/posts/show.json.jbuilder: Esta permite responder en formato json con un único post.
  • app/assets/stylesheets/scaffolds.css.scss: Un archivo general para el CSS del sistema.
​​ Además de esto Scaffold agrega automáticamente en el archivo de manejo de rutas el comando resources :posts. Ahora sólo nos queda agregar la tabla a la base de datos con el comando rake db:migrate. Fíjense que esto es lo único que Scaffold no hace por nosotros y esto es debido a que podemos mejorar nuestro modelo.

Para mostrar una última cosa antes de terminar esta parte del tutorial agregaré un link desde la página principal con esta instrucción ​​<%= link_to 'Ver posts', posts_path %>. Esta función es una pequeña ayuda que nos provee Rails para hacer más fácil el manejo de links, ya que usamos nombres a métodos que son alias de links.

Las vistas resultantes que tendremos son:


Consulta aquí el commit hasta este punto del proyecto.

Ya en la próxima parte de este tutorial estaré con migraciones, consultas a la base de datos y manejo de sesión.

Si algo no queda muy claro siempre me pueden escribir a mi correo tonylattke@gmail.com o también pueden dejar comentarios al final de este post y trataré de ayudarles lo antes posible.

Accede al repositorio del proyecto aquí.