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í.

No hay comentarios:

Publicar un comentario