sábado, 9 de junio de 2012

Tutorial Express de Ruby on Rails: Hacer Un Blog


Bueno, este tutorial lo escribo en particular para un amigo mío, pero si a alguien más le beneficia, está bien... Antes de comenzar, me gustaría dar mi punto de vista sobre el tutorial en sí, ya que en la web encontrarás muchos tutoriales de "Introducción a Rails" que son precisamente enfocados a crear un blog. La gente los ve y dice: "Bueno a mi de qué fregados me va a servir aprender a hacer un blog!?; Dicen que Twitter fue escrito en Rails! ¿Dónde está la magia?" (Al principio cuando me iniciaba en esto de la programación yo pensaba así, no crean que no) Pero después comprendí muchas cosas... Y es en base a eso y a un voto de confianza que me gustaría me dieras, que te pido que te quedes y sigas este tuto si el tema te interesa. Verás, crear un blog es la manera más concisa y correcta de empalmar los conocimientos básicos de un Framework Web, ya que de manera simple (es decir entendible) usamos de todo un poco en cuanto a conceptos. Por otro lado, estoy seguro de que quizá más de uno de ustedes intentó ya seguir uno de estos tutoriales sin resultados, y estoy seguro de que se debió no a ustedes, sino al maestro. Considero que tengo facilidad para enseñar (pues lo he hecho antes) y conozco un poco más de cerca que quizá muchas personas la manera en que trabajan el cerebro y el subconsciente humanos, por lo tanto, sé que éste tutorial es diferente a cualquiera que te hayas topado antes y estoy seguro de que aprenderás algo o bien, se esclarecerán muchas cosas que no entendías... Con eso dicho, Comencemos:

NOTAS: Éste tutorial asume que Sabes Ruby, tienes un entorno Ruby & RoR instalado en tu computadora y por lo menos tienes una idea básica de Etiquetas html Si no sabes casi nada o muy poco de éstas 3 cosas que mencioné, entonces quizá esté tutorial no es para ti todavía... Te invito a checar los enlaces anteriores para darte una idea y volver acá mejor preparado(a), listo para absorber bien el conocimiento que detallaremos aquí. Por si alguien se lo pregunta, para el tutorial se usa Rails 3.2.5 con Ruby 1.9.2, pero cualquier versión de Rails 3.2.x con Ruby 1.9.2 o 1.9.3 estaría bien para seguir el tutorial sin problemas... Y por cierto! este tutorial y el código que generaremos en el hacen a su vez del campo de pruebas perfecto para poner en práctica lo que aprendimos el otro día en el tutorial de git, #SóloUnConsejo...

Como les menciono arriba, hoy construiremos un blog con RoR en este tutorial y con ello consolidaremos conocimientos básicos de Rails que nos ayudarán a continuar con nuestro objetivo de aprender y masterizar dicho framework. En este tutorial no se usará scaffolding para auto generar código, pero tampoco entraremos a cosas más profundas como son RSpec y TDD todavía. La idea es que comprendas más o menos cómo se conforma una webapp rails y cómo puedes armarla para después practicar por ti mismo... Otra cosa importante que tenemos que mencionar es que si nunca has trabajado con un framework que siga el principio/patrón de MVC (Model-View-Controller) entonces quizá no entenderás algunas cosas que aquí se detallen. En caso de que no entiendas el concepto MVC (pero sí sepas ruby) quizá lo mejor para ti es que primero vayas y realices el mini-curso de RailsForZombies y luego regreses acá a poner en práctica, reforzar, comprender y asimilar lo allí aprendido.

Ahora sí, a lo que vamos:

1.- Crear Aplicación y Controlador con Acciones y Vistas

Obviamente, lo primero es crear la aplicación (su esqueleto) con Rails... Fácil. Simplemente corremos:

1
2
3
rails new rubyblog
cd rubyblog
rails g controller Posts index show new create edit update destroy

Explicado: En el comando 1 lo que hacemos es decirle a Rails que queremos crear una aplicación nueva, donde rubyblog se refiere al nombre de la aplicación rails que crearemos. Esto en resumen nos generará un directorio con el nombre de la aplicación que contendrá todos los archivos y carpetas de la misma, Se le puede llamar como uno quiera a nuestra app.

Con el comando 2 nos movemos (dentro de la consola) al directorio de la aplicación recién creada.

Finalmente, con el comando 3 creamos un controlador que dentro contendrá unas acciones predeterminadas junto con sus respectivas vistas (index, show, new, create, edit, update, destroy). Por si tienen problemas entendiendo de lo que hablo, Un controlador es, digamos, un archivo (o grupo de archivos si usamos varios) que va o van a definir el comportamiento de la aplicación web que crearemos, en general lo que definimos en éste archivo más que nada son las formas por medio de las cuales el/los modelos interactuarán con las vistas de la aplicación. Para esto, imaginen los modelos como los archivos o grupos de archivos que describen sus bases de datos, mientras que las vistas son los archivos/páginas que nosotros le mostraremos al usuario en su navegador web.

Resumiendo:


  • En el Modelo va todo lo referente a la base de Datos
  • En la vista va todo lo referente a diseño y Maquetación
  • El controlador es el archivo que define cómo es que se van a comunicar los 2 anteriores.

Por convención, siempre usaremos un nombre Plural y Capitalizado para nombrar el controlador, su nombre debe ser una referencia al nombre del objeto principal que se va a manipular en base a dicho controlador. Como verán, en el ejemplo se usa "Posts" porque el objeto que generalmente se manipula más en un blog son los posts precisamente; Esto quiere decir que generalmente crearemos controladores para los entes más importantes de nuestra aplicación: Pueden ser Usuarios, Posts u otras cosas que queramos manipular (y con "manipular" me refiero a Crear, Leer, Actualizar y Destruir) dentro de la webapp.

Para esto, cabe destacar que el controlador se guarda en el directorio de app/controllers de nuestro proyecto con la nomenclatura: nombre_controller.rb y las vistas están en app/views/nombrecontrolador con la nomenclatura: acción.html.erb;

¿Qué quiere decir ésto?

Bueno. Si abrimos el controlador en nuestro editor de código o IDE favorito (Les recomiendo gedit vitaminado) vamos a ver que se trata de un simple archivo de ruby que incluye varios métodos definidos con el nombre de las acciones que escogimos:

Click para agrandar

Como nos enseñaron desde la primaria, una acción es aquello que queremos/vamos a hacer, y las describimos en nuestra lengua por medio de los verbos. Los que tengan noción de Ruby sabrán que los métodos son los equivalentes a los verbos del español en este lenguaje y que, por ende, éste archivo llamado controlador es el que define las acciones de nuestra aplicación por medio de los métodos que nosotros escribiremos. A lo mejor reconoces todas las acciones descritas en el archivo, pues son simples verbos (crear, actualizar, destruir etc.) Pero quizá los primeros 2 nombres te resulten confusos: index y show. Bueno: index es la acción (método) que define a nuestra página principal y cómo mostraremos información ahí, mientras que show es la acción/método que describe cómo mostraremos los objetos individuales de nuestro ente (objeto más importante) del controlador. En el ejemplo, esto quiere decir que index va a definir el comportamiento de nuestra página principal del blog cuyo propósito es mostrar todos los posts y show por su parte se encargará de definir el método por medio del cual tomaremos y mostraremos las páginas (vistas) de cada post individual.

NOTA: Estas mismas acciones que generamos aquí son las acciones base que ocuparás en prácticamente cualquier controlador rails de cualquier proyecto que realices generalmente.

Sobre las vistas, si abrimos una veremos algo parecido a lo siguiente:

Click para agrandar

Una vista no es más que una página HTML, la cual se encarga de mostrar contenido al navegador. Su extensión es .html.erb porque las páginas HTML que usamos en Rails pueden contener código ruby embedido, esto quiere decir que para maquetar una página HTML en RoR puedes usar todo el HTML que conozcas (aderezado con Javascript, CSS etc.) y además puedes utilizar código ruby dentro de ella, mismo que renderizará y/o funcionará en el navegador siempre y cuando esté dentro de las etiquetas:

<%= Insertar Código Aquí  %> o bien <% Insertar Código aquí  %>

Respectivamente. Explicaré más sobre ésto y las vistas en específico dentro de poco... No te desesperes.

2.- Definiendo Rutas

Las rutas son todo aquello que define el nombre y dirección de las URL dentro de tu aplicación web, la manera más fácil y práctica de crearlas es generando un recurso, que en idioma de programador es "rutas RESTful de un ente/objeto" de la aplicación web. En nuestra app del ejemplo el único objeto/ente que manipulamos son los posts, por lo tanto generaremos un recurso RESTful para los posts precisamente. Crear un recurso es fácil, sólo añade:

resources :objeto

a tu archivo routes.rb que se encuentra dentro de config... Hay otras maneras de crear rutas, y como verás en el archivo routes.rb cuando lo abras, habrá algo así:

Click para agrandar

Esto es porque rails nos generó unas rutas manualmente para cada acción, y puedes generarlas así tu también, pero lo idóneo es hacerlo en base a recursos, ya que es más fácil y funcional. Editaremos ése archivo de manera que nos quede así:

Click para agrandar

Y si no entiendes porqué, no te preocupes, lo importante es que comprendas que por cada ente/objeto principal que quieras manipular en tu aplicación debes crear un recurso para el mismo en tu archivo routes.rb como le hicimos ahorita con los posts.

Lo siguiente que haremos (aprovechando que estamos en el archivo de las rutas) será definir cuál será la página principal de nuestra aplicación web, o más bien, hacia donde apuntará la URL madre (por ejemplo http://www.myapp.com/); Esto se logra añadiendo una línea como esta a nuestro routes.rb:

root :to => "posts#index"

Para el ejemplo esa línea es la indicada, pero si estuviéramos haciendo otra cosa, reemplazaríamos posts por el nombre del controlador e index por el nombre de la acción que queremos que se haga cargo. Obviamente dicha acción deberá tener una vista ya definida para que pueda mostrar algo... El archivo routes.rb termina viéndose así:

Click para Agrandar
Y si todo ha salido bien, es hora de iniciar nuestro servidor para ver cómo van las cosas. Estando dentro del directorio de nuestro proyecto con nuestra consola, corremos:

rails s

y esto iniciará el servidor... Nos vamos a http://localhost:3000 en nuestro navegador web y veremos algo como ésto:

Click para Agrandar

(P.D. Siéntete libre de explorar esa página y sus enlaces); Por otro lado, si nos vamos a http://localhost:3000/posts veremos algo así (la página principal de nuestra aplicación):

Click para Agrandar

Pero hey! si http://localhost:3000 equivale a lo que sería la página principal de nuestra webapp en un entorno de producción (de momento está corriendo en nuestra computadora solamente y no en la web)  entonces porqué no renderiza la página index directamente si ya lo configuramos así en el routes.rb anteriormente con root :to? Muy simple: Porque tenemos otro index dentro de la aplicación, el cual se encuentra en el directorio "public" donde se guardan principalmente páginas y contenidos estáticos. Para que nuestra app muestre lo que debe al acceder a la raíz y no la página de bienvenida, debemos eliminar dicha página, desde consola o desde nuestro explorador de archivos. La página en cuestión que debemos eliminar es public/index.html y una vez eliminada, si accedemos a nuestra url http://localhost:3000 y refrescamos el navegador veremos la verdadera página principal, aquella que especificamos en routes.rb anteriormente.

NOTA: Todo lo que metas en public renderizará desde la raíz en adelante, por ejemplo si yo tengo en el directorio public una página que se llame "holamundo.html", al acceder a http://localhost:3000/holamundo.html veré dicha página.

3.- Modelos

Ya explicamos lo que es un Modelo arriba en el post. Ahora lo generaremos... Estando dentro del directorio de nuestra app con la consola, correremos el comando:

rails g model Post title:string content:text

Que lo que hará será crear un modelo (esqueleto de tabla de base de datos para rápido) que contendrá la información de nuestro ente principal. Los modelos siempre se tienen que nombrar igual que el controlador del ente al que correspondan pero en singular y capitalizados, como verán en el ejemplo, debido a que nuestro controlador es Posts nuestro modelo generado se llama Post, justo después del nombre, tenemos que poner los campos que tendrán cada uno de los objetos que vayamos a generar (en este caso posts) que tienen como campos un titulo del tipo "string" (Cadena de texto en Ruby) y un contenido que es simplemente un área de texto. Si tienes experiencia con otros frameworks y bases de datos, te preguntarás porqué no generamos un id. Ésto se debe a que en Rails el ID se genera automáticamente cada que creamos un objeto para nuestra base de datos... En pocas palabras el campo de ID está ahí, pero no lo especificas tu y no tienes porqué. Cada objeto que creemos tendrá un ID diferente (1, 2, 3, etc), de forma automática.

Ahora tenemos que migrar nuestra base de datos para que use la interfaz ActiveRecord de Rails (hablaremos de ésto poquito más adelante) y se haga como tal; La migración se hace con:

rake db:migrate

Como el modelo es el archivo que establece la configuración de nuestra base de datos, seguro muchos de ustedes pensarán que es algo mágico y complicado, ¡pero no lo es! los invito a verlo:

Click para Agrandar

Básicamente un modelo se trata de un archivo de Ruby guardado en app/models con el nombre que le pusimos y terminación rb que describe por medio de una clase un objeto individual de lo que sería el ente que manipularemos en nuestra webapp (En este caso 1 Post) y pues lo que describe más que nada es el nombre del objeto individual (nótese que se capitaliza) y hace que herede de "ActiveRecord::Base" que en términos simples se trata de la interfaz Rails por medio de la que gestionamos nuestra base de datos. Luego le otorga los atributos que pedimos y denota que son accesibles.

Para todos aquellos que han usado otros frameworks en el pasado (o bien bases de datos) aquí es donde empieza la parte en la que adorarán a Rails, verán: Sin importar en qué base de datos desarrollemos, con Ruby on Rails no tenemos que sabernos los comandos de gestión de dicha base de datos, puesto que todo se maneja en base a ActiveRecord, el ayudante para bases de datos de Rails. Las cosas que haremos por medio de ActiveRecord serán Crear, Leer, Actualizar y Eliminar objetos de nuestra base de datos y gracias a estos comandos podremos hacer que la interfaz de nuestra aplicación web lo haga también. (No entraré a detalle en ActiveRecord pero si te interesa conocerlo a fondo, checa RailsForZombies); Sin embargo, si dejaré unos ejemplos básicos en pastebin rápidamente:

  1. # ActiveRecord CRUD (Create-Read-Update-Destroy)
  2.  
  3. # CREAR POSTS:
  4.  
  5. Post.create(:title => "Nuestro Primer Post", :content => "Contenido para el primer post")
  6.  
  7. # LEER/ENCONTRAR POSTS:
  8.  
  9. Post.all  # (todos)
  10.  
  11. Post.find(id)  # (uno)
  12.  
  13. # Después de encontrar 1 post:
  14.  
  15. Post.title  # (Nos regresa el título de ese post)
  16. Post.content  # (Nos regresa el contenido de ese post)
  17.  
  18. # ACTUALIZAR POSTS:
  19.  
  20. post.update_attribute(:content, "Contenido Cambiado")  
  21.  
  22. # (cambia 1 atributo) [con/de la variable "post" definida con los métodos de LEER]
  23.  
  24. post.update_attributes(:title => "Primer Post", :content => "El contenido")  
  25.  
  26. # (para cambiar todos los atributos) [con/de la variable "post" definida con los métodos de LEER]
  27.  
  28. # DESTRUIR POSTS:
  29.  
  30. post.destroy(id)  # [con variable "post" que nosotros elijamos según id]


Ahora bien, por si no has captado la relación, nuestro modelo hace que los objetos individuales que creemos para nuestro Ente de datos hereden directamente de ActiveRecord::Base para 2 cosas: 

  1. Que nazcan y pertenezcan en/a nuestra base de datos
  2. Que podamos manipularlos con una serie de comandos predefinidos dentro del código rails (ActiveRecord) a todos para dar funcionalidad a la interfaz. 

Esto quiere decir que lo que queremos lograr es que haya una página web que nos permita CREAR POSTS por ejemplo, una para EDITARLOS y ELIMINARLOS entre otras cosas. Todas estas acciones se consiguen a través de la conexión con la base de datos que establecemos con el modelo.

4.- Más sobre rutas

Si corremos el comando:

rake routes

Estando dentro del directorio de nuestra app en terminal, veremos algo como esto:

Click para Agrandar

Este comando nos da la información detallada sobre nuestras rutas, qué método HTTP ocupan, cuál es su "path" en la aplicación, cómo es que se amm... concatena/genera ese path y qué combinación de controlador#acción las comanda. Si tu output se ve más o menos como el mío, entonces significa que hasta aquí vas bien y también significa que puedes iniciar tu servidor local con rails s en terminal y al visitar por ejemplo http://localhost:3000/posts/new verás algo como ésto:

Click para Agrandar

Las preferencias de cómo se debe llamar cada ruta y a donde debe de llevar (si "no nos gustan" los defaults) se actualizan/modifican en nuestro routes.rb con parámetros, métodos y atributos como matchas e incluso redirect_to según el caso... Todo eso lo pueden aprender bien a bien en RailsForZombies.

Es importante que sepan que cuando vamos a referirnos a una ruta en nuestro código de la aplicación (para por ejemplo establecer acciones en el controlador y así) la nombramos por como la consola nos la muestra en el output de rake routes y le añadimos _path al final, esto quiere decir que en mi código si me quiero referir a la ruta que sirve para EDITAR un post, usaría la variable edit_post_path por ejemplo y a esta URL le puedo pasar parámetros (como el ID del post y demás) pero eso lo explicaremos más adelante.

Una cosa más: ¿Recuerdas que desde el principio generamos acciones para nuestro controlador y también vistas? Pues bueno: Hay acciones que no requieren vista, porque simplemente son sucesos y no cosas que hace el usuario directamente por medio de una interfaz. Éstas acciones son Create, Destroy y Update... Como sus vistas no son necesarias, las eliminaremos de nuestro directorio app/views/posts (Los archivos a eliminar concretamente son create.html.erb, destroy.html.erb, update.html.erb) y proseguiremos con nuestro tutorial.

5.- Validaciones

¿Recuerdas cuando abrimos el archivo del modelo? Parecía muy simple cierto? Pues bien. Un archivo de modelo también nos sirve para definir validaciones en nuestra aplicación web. Esto quiere decir, declarar planes de acción en caso de que X o Y condiciones se cumplan o no se cumplan. Podemos validar muchos datos y características dentro de nuestro modelo, tales como la presencia, longitud y originalidad de un campo específico, entre otras. Para el ejemplo usaremos el siguiente código de validaciones (va en app/models/post.rb):

validates :title, :content, :presence => true
validates :title, :length => { :minimum => 2 }
validates :title, :uniqueness => { :message => "El titulo ya se uso" }

El archivo en cuestión queda así:

Click para agrandar

Y pues lo que esto hará será checar (En éste orden): La presencia del título y del contenido, el tamaño del título (que deberá ser de mínimo 2 caracteres) y también la originalidad del mismo, esto quiere decir que no puede estar repetido. En el caso de la originalidad del título (línea 3) como verán hemos establecido un mensaje específico a soltar cuando el error (título duplicado) se suscite.

6.- Controlador-Vista

Ahora lo que tenemos que hacer es definir Qué van a hacer nuestras vistas y en sí, cómo será el workflow de la aplicación también. Empezaremos por escribir código en las acciones de nuestro controlador (llenar los métodos) y por cada método rellenado, escribiremos la vista que realizará dicha acción/acciones predeterminadas. Explicaré este proceso 1 por 1 con todas las acciones que se ocupan (Index al final):

Acción Show (app/controllers/posts_controller.rb)

Esta acción lo que tiene que hacer es buscar un post individualmente y regresar su ID para que (en base a lo que escribamos en nuestras vistas) lo podamos abrir en una página con una URL del tipo .../posts/id para verlo. El método como ya sabemos es Show y el código que va en ese Método es:

 def show
 @post = Post.find(params[:id])
 end

Que hace exactamente lo que necesitamos. Encuentra un Post en base a su parámetro de ID, Ahora depende de nosotros como manipulemos ese dato en base a las vistas. Aquí aclaremos que creamos la variable de instancia "@post" porque vamos a manipular ese objeto mucho (ya que es nuestro objeto principal) no importa si no entiendes del todo este concepto, lo que importa es que entiendas que regularmente, cuando te quieras referir a un ente específico en un método dentro de un controlador, se tiene que describir como una variable de instancia que lleve el nombre del objeto individual y luego determine la acción.

Vista Show (app/views/posts/show.html.erb)

La vista Show lo que hará será simplemente ser una página individual para mostrar un post con su título y contenido (además de la fecha de creación) en base a su ID. El código para lograr ésto es el siguiente:

<h1><%= @post.title %></h1>
<p><%= @post.content %></p>
<small><%= @post.created_at %></small>

Acción New (app/controllers/posts_controller.rb)

Ahora tenemos que definir la acción para crear un nuevo post en nuestro controlador, dicha acción es new y lo que hace es crear un nuevo post precisamente jajajaja, el código para lograr ésto es el siguiente:

 def new
 @post = Post.new
 end

Vista New (app/views/posts/new.html.erb)

En la vista New simplemente debemos de crear un formulario que nos permita crear un post nuevo, soltando advertencias si hay errores basados en nuestras validaciones. El código para hacer esto es:

  1. <h1>Nuevo post</h1>
  2.  
  3. <%= form_for @post do |f| %>
  4.         <% if @post.errors.any? %>
  5.                 <h2>Errores:</h2>      
  6.                 <ul>
  7.                         <% @post.errors.full_messages.each do |message| %>
  8.                                 <li><%= message %></li>
  9.                         <% end %>
  10.                 </ul>
  11.         <% end %>
  12. <p>
  13.         <%= f.label :title %><br />
  14.         <%= f.text_field :title %><br />
  15. <br />
  16.         <%= f.label :content %><br />
  17.         <%= f.text_area :content %>
  18. </p>
  19. <p>
  20.         <%= f.submit "Agregar Nuevo Post" %>
  21. </p>
  22. <% end %>


Acción Create (app/controllers/posts_controller.rb)

La acción create no tiene vista, así que sólo tenemos que definir el método con el siguiente código en el controlador:

 def create
 @post = Post.new(params[:post])

  if @post.save
  redirect_to posts_path, :notice => "Post Guardado!"
  else
  render "new"
         end
 end

Como ya explicamos anteriormente, Create no tiene vista porque se trata de una acción para un suceso, es decir, sólo describe el momento en que un nuevo post es creado. Toma como variable el resultado de post.new y específicamente los datos (parámetros) de ese post para validar. Luego, hacemos un condicional de if para confirmar que si el post se guarda, redireccionemos al usuario a la raíz de la aplicación (URL principal representada por la variable posts_path si recuerdas lo de las rutas) y le damos un flash message que dice "Post Guardado!" (Un flash message es una notificación en la parte de arriba del navegador). Luego explicamos (con el bloque de else) que si el post no se guarda, regresemos al usuario a la página de creación de posts (vista new) y finalmente terminamos el método y los bloques.

Acción Edit (app/controllers/posts_controller.rb)

La acción Edit lo que hace es encontrar un post específico por su parámetro ID para luego pasarle ese dato a la vista de edición, donde precisamente editaremos el post en base a una interfaz. El código para nuestro método edit que hace que encontremos un post por su parámetro de ID es:

 def edit
 @post = Post.find(params[:id])
 end

Y lo que hace es precisamente eso, encuentra un post indicado en base a su parámetro de ID y lo guarda en una variable de instancia que se llama @post.

Vista Edit (app/views/posts/edit.html.erb)

Ahora necesitamos una interfaz por medio de la cual el usuario pueda editar su post, y esto se hace con la vista Edit, cuyo código es el siguiente:

  1. <h1>Editar Post</h1>
  2.  
  3. <%= form_for @post do |f| %>
  4.         <% if @post.errors.any? %>
  5.                 <h2>Errores:</h2>      
  6.                 <ul>
  7.                         <% @post.errors.full_messages.each do |message| %>
  8.                                 <li><%= message %></li>
  9.                         <% end %>
  10.                 </ul>
  11.         <% end %>
  12. <p>
  13.         <%= f.label :title %><br />
  14.         <%= f.text_field :title %><br />
  15. <br />
  16.         <%= f.label :content %><br />
  17.         <%= f.text_area :content %>
  18. </p>
  19. <p>
  20.         <%= f.submit "Actualizar Post" %>
  21. </p>
  22. <% end %>


Esto le presentará un formulario al usuario donde podrá hacer la edición del post que quiera, lo que simplemente significa cambiar los atributos de un objeto Post de nuestra base de datos con una interfaz gráfica.

Acción Update (app/controllers/posts_controller.rb)

La acción update lo que hace es representar el suceso por medio del cual un post es actualizado (se le cambian los atributos con la vista de edit) dándonos un flash message para avisar. Su código es el siguiente:

  1.         def update
  2.         @post = Post.find(params[:id])
  3.        
  4.         if @post.update_attributes(params[:post])
  5.                 redirect_to posts_path, :notice => "Tu post se ha actualizado"
  6.         else
  7.                 render "edit"
  8.         end
  9. end


Lo que hacemos aquí es primero encontrar un post por su id y guardarlo en una variable de instancia llamada @post, luego, verificamos con if si los atributos del post han sido cambiados y resultó exitoso el cambio, de lo contrario (gracias a else) renderizamos la vista de "Edit" otra vez explicando el error de ser posible.

Acción Destroy (app/controllers/posts_controller.rb)

Sirve para ELIMINAR posts. No tiene vista y el código para ésta es el siguiente:

  1.         def destroy
  2.         @post = Post.find(params[:id])
  3.         @post.destroy
  4.         redirect_to posts_path, :notice => "Tu post se ha Borrado"
  5.         end
  6. end

Lo que hacemos primero es encontrar un post por id, guardarlo en nuestra variable de instancia y luego lo borramos de la base de datos (y por ende del blog) con el método Destroy, soltamos un flash message al usuario después de borrar y listo.

Finalmente, lo que haremos será crear la acción para Index y su vista, que lo que harán será representar la página principal de nuestro blog con todos los posts y botones (enlaces en éste caso) para el mismo. 

Acción Index (app/controllers/posts_controller.rb)

 Esta acción lo que tiene que hacer es simplemente encontrar TODOS los posts en la base de datos para mostrarlos en la página, se logra con:

  def index
    @posts = Post.all
  end

Y con esto, terminamos nuestro controlador de posts... El código completo del mismo es:

  1. class PostsController < ApplicationController
  2.  
  3.   def index
  4.     @posts = Post.all
  5.   end
  6.  
  7.         def show
  8.                 @post = Post.find(params[:id])
  9.         end
  10.        
  11.         def new
  12.                 @post = Post.new
  13.         end
  14.  
  15.         def create
  16.                 @post = Post.new(params[:post])
  17.  
  18.                 if @post.save
  19.                         redirect_to posts_path, :notice => "Tu post se ha salvado"
  20.                 else
  21.                         render "new"
  22.                 end
  23.         end
  24.        
  25.         def edit
  26.         @post = Post.find(params[:id])
  27.         end
  28.  
  29.         def update
  30.         @post = Post.find(params[:id])
  31.        
  32.         if @post.update_attributes(params[:post])
  33.                 redirect_to posts_path, :notice => "Tu post se ha actualizado"
  34.         else
  35.                 render "edit"
  36.         end
  37. end
  38.  
  39.         def destroy
  40.         @post = Post.find(params[:id])
  41.         @post.destroy
  42.         redirect_to posts_path, :notice => "Tu post se ha borrado"
  43.         end
  44. end


para que vayan cotejando si se equivocaron o no.

Vista index (app/views/posts/index.html.erb)

Esta es la página principal de nuestro blog! lo que toda la gente verá, su código es el siguiente:

  1. <h1> Nuestro Blog </h1>
  2.  
  3. <% @posts.each do |post| %>
  4. <h2><%= link_to post.title, post %></h2>
  5. <p> <%= post.content %> </p>
  6. <p> <%= link_to "Editar", edit_post_path(post) %> |
  7. <%= link_to "Borrar", post, :confirm => "Estas seguro?", :method => :delete %>
  8. </p>
  9. <hr />
  10. <% end %>
  11. <p><%= link_to "Agregar nuevo post", new_post_path %></p>

Lo que esto hace, es definir el título del blog, luego un bloque de código ruby que muestra todos los posts y luego una plantilla para dar formato a los datos de los posts que de ese bloque salgan. También tenemos enlaces a las acciones de Edit, Delete (esta última pide confirmación y a la de New en ésta página como podrán ver.

7.- Plantillas y Ruby en las vistas

Como habrás visto arriba, siempre que escribimos código Ruby en una página HTML.ERB lo ponemos entre unas etiquetas que son <%=   %> y <%   %> las primeras son para escribir código ruby que queremos que se imprima en la página, tal como por ejemplo el bloque de código que suelta todos los posts en la vista index para que éstos se impriman al navegador. Las segundas son para todo aquel código ruby que necesitamos en la página pero que no queremos que se muestre (o renderice pues en el navegador), tal como cuando por ejemplo, hacemos un end de ruby para un bloque o método.

Ahora, en tu directorio app/views verás que hay una subcarpeta que se llama layouts ¿Para qué es? Bueno, esta carpeta guarda las plantillas generales de las vistas de la aplicación. Cuando creamos una vista solo escribimos el código específico de esa vista, pero al ser una página html lleva una declaración, un header y un body por ejemplo no? donde va eso? todo eso lo provee la plantilla, al igual que los enlaces a CSS, Javascripts y demás. También va el código específico para mostrar flash messages en nuestras páginas por ejemplo entre otras funcionalidades. Ahora es necesario que abras tu archivo app/views/layouts/application.html.erb y pegues este código:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.   <title>Blog</title>
  5.   <%= stylesheet_link_tag    "application", :media => "all" %>
  6.   <%= javascript_include_tag "application" %>
  7.   <%= csrf_meta_tags %>
  8. </head>
  9. <body>
  10.  
  11. <% flash.each do |key, value| %>
  12. <p> <%= value %> </p>
  13. <% end %>
  14.  
  15. <%= yield %>
  16.  
  17. </body>
  18. </html>

Lo que ves aquí es la estructura básica de una página web en HTML 5 con un poco de código Ruby en ella, de aquí lo importante es que entiendas que todo el código que esté escrito en este archivo se usará y renderizará en TODAS las vistas de la aplicación, por lo tanto si tienes código que usarás muchas veces, en lugar de duplicarlo en tus vistas individuales, puedes ponerlo aquí o en una parcial (¡a googlear!) según sea necesario. Por otro lado, es importante que entiendas que las líneas:

1
2
3
<%= stylesheet_link_tag    "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>

Lo que hacen es lo siguiente: La 1 toma todas las hojas CSS del directorio app/assets/stylesheets y las inserta en tu plantilla y por lo tanto en tus vistas con la (o las) etiquetas HTML correspondientes. Lo mismo con la línea 2 pero con los Javascripts. Finalmente la línea 3 pasa unos parámetros para evitar que hackeen nuestra aplicación web, de eso no te preocupes.

Ahora, la línea:

<%= yield %>

Lo que hace es insertar el código particular de cada vista individual en el lugar donde yield está ubicado dentro de la plantilla.

8.- Finalizando y Tareas...

Una vez que ya terminamos el controlador, las vistas y la plantilla, nuestra aplicación está lista para correr, inicia tu servidor y al visitar http://localhost:3000 verás el resultado final terminado. Si todo salió bien, verás algo como esto:

Click para Agrandar


Ahí podrás crear, editar y borrar nuevos posts con los enlaces que ahí tienes a la mano, haz algunos.

Ahora, un blog bien hecho no deja que cualquiera acceda a crear posts verdad? te queda de tarea investigar cómo añadirle autorización/autenticación a tu blog y además tratar de eliminar el código duplicado de tus vistas (como en edit y new) en base a una parcial. También, tomando en cuenta lo de los CSS, Javascript y demás en app/assets, te recomiendo cambiar el diseño y editando las páginas de "public" añadir una de 404 error que renderice cuando de hecho haya un error 404

Todo esto podrás hacerlo si sigues RailsForZombies y por ejemplo, checas los tutoriales en video RailsCasts o preguntas en Stack Overflow... Por mi parte de momento, esto es todo. Espero que te hayas divertido y hayas entendido el tutorial.

La próxima hacemos TDD con RSpec, Promesa ;)

1 comentarios:

  1. Excelente tutorial :) ya me dan ganas de empezar a aprender ruby que es mi siguiente objetivo despues de dominar Python :D

    ResponderSuprimir

Original text