Ruby On Rails
Ruby On Rails
Ruby On Rails
Introduccin a Rails
LIBROSWEB | www.librosweb.es
Contenido
Captulo 1. Antes de empezar ........................................................................................................ 3
Captulo 2. Qu es Rails? ............................................................................................................. 4
Captulo 3. Creando un nuevo proyecto ....................................................................................... 5
3.1. Instalando Rails .................................................................................................................. 5
3.2. Creando la aplicacin de Blog ........................................................................................ 6
Captulo 4. Hola, Rails! .................................................................................................................... 9
4.1. Iniciando el Servidor Web ................................................................................................ 9
4.2. Hola Mundo ........................................................................................................................ 11
4.3. Estableciendo la pgina principal ................................................................................ 12
Captulo 5. Creando un nuevo post ................................................................................................... 15
5.1. Primeros pasos ...................................................................................................................... 16
5.2. El primer formulario ........................................................................................................... 19
5.3. Creando artculos ................................................................................................................. 21
5.4. Creando el modelo Article .............................................................................................. 22
5.5. Migraciones ........................................................................................................................... 23
5.6. Guardando datos en el controlador .................................................................................... 24
5.7. Mostrando artculos ............................................................................................................. 26
5.8. Listando todos los artculos ................................................................................................. 27
5.9. Aadiendo enlaces ................................................................................................................ 29
5.10. Aadiendo validaciones ..................................................................................................... 30
5.11. Actualizando artculos ....................................................................................................... 34
5.12. Usando parciales para eliminar las duplicidades en las vistas ....................................... 37
5.13. Borrando artculos ............................................................................................................. 39
Captulo 6. Aadiendo otro modelo ............................................................................................. 43
6.1. Generando el modelo ...................................................................................................... 43
6.2. Asociando modelos ......................................................................................................... 45
6.3. Aadiendo una ruta para los comentarios ................................................................ 46
6.4. Generando un controlador............................................................................................. 46
Captulo 7. Refactorizacin ........................................................................................................... 53
7.1. Renderizando colecciones de parciales..................................................................... 53
7.2. Renderizando un formulario parcial ............................................................................ 55
Captulo 8. Borrando comentarios ............................................................................................... 57
Programming Ruby.
Captulo 2. Qu es Rails?
Rails es un framework de desarrollo de aplicaciones web escrito en el lenguaje de
programacin Ruby. Est diseado para hacer que la programacin de
aplicaciones web sea ms fcil, haciendo supuestos sobre lo que cada
desarrollador necesita para comenzar. Te permite escribir menos cdigo
realizando ms que muchos otros lenguajes y frameworks. Adems, expertos
desarrolladores en Rails reportan que hace que el desarrollo de aplicaciones web
sea ms divertido.
Rails es un software dogmtico. ste asume que existe una forma "mejor" de
hacer las cosas, y est diseado para fomentar esa forma - y en algunos casos
para desalentar alternativas.
Si aprendes "El Modo Rails" probablemente descubrirs un tremendo incremento
en tu productividad. Si persistes trayendo viejos hbitos de otros lenguajes a tu
desarrollo en Rails, e intentas usar patrones aprendidos en otros lugares, podras
tener una experiencia menos agradable.
La filosofa de Rails se basa en estos dos principios:
DRY (del ingls, "Don't Repeat Yourself") - sugiere que escribir el mismo
cdigo una y otra vez es una mala prctica.
Una vez comprobado que tienes tanto Ruby como SQLite 3, para instalar Rails,
usa el comando proporcionado por RubyGems gem install:
$ gem install rails
Para verificar que tu instalacin est correcta, deberas poder ejecutar lo siguiente:
$ rails --version
Esto crear una aplicacin Rails llamada Blog en un directorio llamado blog e
instalar las dependencias (gemas) que estn mencionadas en el Gemfile usando
el comando bundle install.
Puedes ver todas las opciones que el generador de nuevas aplicaciones
provee, ejecutando rails new -h.
Despus de crear la aplicacin, entra a su directorio para continuar trabajando
directamente en la aplicacin:
TRUCO
$ cd blog
El comando rails new blog que acabamos de ejecutar, cre una carpeta en tu
directorio de trabajo llamado blog. El directorio blog tiene un nmero de archivos
autogenerados y carpetas que conforman la estructura de una aplicacin Rails.
La mayora del trabajo en este tutorial se llevar a cabo en la carpeta app/, as que
primero hagamos un repaso rpido al propsito de cada archivo y carpeta de
Rails:
Archivo/Carpeta
Propsito
app/
config/
config.ru
db/
doc/
GemfileGemfile.lock
lib/
log/
public/
La nica carpeta vista por el mundo tal como es. Contiene los
archivos estticos y assets compilados.
Archivo/Carpeta
Propsito
Rakefile
Este archivo localiza y carga tareas que pueden ser ejecutadas desde
la lnea de comandos. La lista de tareas son definidas a travs de los
componentes de Rails. En vez de cambiar el Rakefile, deberas
agregar tus propias tareas, aadiendo archivos al
directorio lib/tasks de tu aplicacin.
README.rdoc
script/
test/
tmp/
vendor/
Rails: sta asegura que tienes el software configurado correctamente para servir
una pgina. Tambin puedes hacer click en el link About your application's
enviroment para ver un resumen del entorno de tu aplicacin.
Rails crear una serie de archivos y aadir una ruta por ti.
create
route
invoke
app/controllers/welcome_controller.rb
get "welcome/index"
erb
create
app/views/welcome
create
app/views/welcome/index.html.erb
invoke
create
test_unit
test/functional/welcome_controller_test.rb
invoke
helper
create
app/helpers/welcome_helper.rb
invoke
test_unit
create
invoke
invoke
create
invoke
create
test/unit/helpers/welcome_helper_test.rb
assets
coffee
app/assets/javascripts/welcome.js.coffee
scss
app/assets/stylesheets/welcome.css.scss
A continuacin, tienes que indicarle a Rails donde est ubicada tu pgina principal.
Para ello, abre el archivoconfig/routes en tu editor:
Blog::Application.routes.draw do
get "welcome/index"
El root :to => "welcome#index" le indica a Rails que debe asociar las peticiones
de la raz de la aplicacin a la accinindex del controlador welcome y get
"welcome/index" le indica a Rails que asocie peticiones
Si ejecutas el comando rake routes, vers que se han definido varias rutas para todas las
acciones estndar de las aplicaciones RESTful. Ms adelante se explicar el significado de
cada columna. Por ahora so fjate en que Rails ha inferido que la palabra en singular del
recurso articles es article, con lo que el resultado es el siguiente:
$ bin/rake routes
Prefix Verb
articles GET
POST
new_article GET
edit_article GET
article GET
URI Pattern
Controller#Action
/articles(.:format)
articles#index
/articles(.:format)
articles#create
/articles/new(.:format)
articles#new
/articles/:id/edit(.:format) articles#edit
/articles/:id(.:format)
articles#show
PATCH
/articles/:id(.:format)
articles#update
PUT
/articles/:id(.:format)
articles#update
DELETE /articles/:id(.:format)
root GET
articles#destroy
welcome#index
Figura 5.2 Error de enrutamiento en Rails (ninguna ruta est configurada para servir
/articles/new)
Este error se produce porque la ruta necesita tener asociado un controlador para poder
servir las peticiones. As que la solucin es tan sencilla como crear un controllador
llamado ArticlesController. Si no quieres crearlo a mano, ejecuta el siguiente comando:
$ bin/rails g controller articles
Para aadir una accin a mano en un controlador, lo nico que necesitas es crear un nuevo
mtodo en el controlador. Abre el archivo app/controllers/articles_controller.rb y
dentro de la clase ArticlesController define un nuevo mtodo de esta manera:
def new
end
Vaya rollo de texto, verdad? Repasemos rpidamente cada parte de ese texto.
La primera parte identifica la plantilla que est faltando. En este caso, es la
plantila articles/new. Rails primero buscar esta plantilla. Si no la encuentra, luego
tratar de cargar la plantilla llamada application/new. El motivo es que tu
controlador ArticlesController hereda del controlador base ApplicationController.
La siguiente parte del mensaje contiene un mapa (en ingls, hash). La clave :locale en
este mapa simplemente indica el idioma para el que se debe obtener la plantilla. Por
defecto, est configurado en ingls (cdigo en).
La siguiente clave, :formats especifica el formato de la plantilla que ser servido en la
respuesta. El formato por defecto es :html, por lo que Rails busca una plantilla HTML. La
ltima clave, :handlers, nos dice qu manejador de plantilla (en ingls, template handler)
se puede usar para renderizar la plantilla. :erb es el manejador ms usado para plantillas
HTML, :builder se usa para plantillas XML, y :coffee usa CoffeeScript para construir
plantillas JavaScript.
La ltima parte del mensaje de error indica los lugares en los que Rails ha buscado las
plantillas. En una aplicacin Rails como esta las plantillas se guardan en un nico
directorio. Pero en aplicaciones ms complejas, las plantillas podran encontrarse repartidas
en varias localizaciones.
La plantilla ms simple que funcionara en nuestro caso sera una localizada
en app/views/articles/new.html.erb. La extensin de este nombre de archivo es muy
importante: la primera extensin define el formato de la plantilla, y la segunda extensin
el manejador de plantilla que se usar.
Rails tratar de encontrar una plantilla llamada articles/new en el directorio app/views.
El formato para esta plantilla slo puede ser html y el manejador debera
ser erb, builder o coffee. Ya que quieres crear un nuevo formulario HTML, tendrs que
usar el lenguaje ERB. Por lo tanto el archivo debera llamarse articles/new.html.erb y
debe encontrarse dentro de la carpeta app/views de la aplicacin.
Ahora crea un nuevo archivo en app/views/articles/new.html.erb y escribe el siguiente
contenido en l:
<h1>New Post</h1>
<p>
<%= f.label :text %><br>
<p>
<%= f.submit %>
</p>
<% end %>
Prefix Verb
articles GET
POST
new_article GET
edit_article GET
article GET
URI Pattern
Controller#Action
/articles(.:format)
articles#index
/articles(.:format)
articles#create
/articles/new(.:format)
articles#new
/articles/:id/edit(.:format) articles#edit
/articles/:id(.:format)
articles#show
PATCH
/articles/:id(.:format)
articles#update
PUT
/articles/:id(.:format)
articles#update
DELETE /articles/:id(.:format)
root GET
articles#destroy
welcome#index
El helper articles_path le dice a Rails que apunte el formulario a la URI asociada con el
prefijo articles, por lo que el formulario enviar por defecto peticiones POST a esa ruta.
Como ves, esta ruta est asociada con la accin create del controlador
actual, ArticlesController.
Con el formulario y su ruta asociada definidas, ahora ya puedes rellenar el formulario y
pinchar en el botn de enviar para empezar el proceso de creacin de un nuevo artculo. No
obstante, cuando enves el formulario vers el siguiente mensaje de error que ya debera
resultarte familiar:
end
def create
end
end
Si ahora reenvas el formulario, vers otro error comn: falta la plantilla. Por el momento
vamos a ignorar este error, ya que la accin create s que est al menos guardando el
nuevo artculo en la base de datos.
Cuando se enva un formulario, los campos del formulario se envan a Rails
como parmetros. Estos parmetros se pueden obtener dentro de las acciones del
controlador, ya que normalmente tu cdigo los necesita para completar sus tareas. Para ver
cmo son parmetros, cambiar la accin create a esto:
def create
render plain: params[:article].inspect
end
Ahora esta accin muestra los parmetros que se envan mediante el formulario que crea
nuevos artculo. En cualquier caso, de momento esto no nos sirve para nada. Aunque es
cierto que puedes ver el contenido de los parmetros, no estamos haciendo nada con ellos,
por lo que su valor se pierde.
Con ese comando le decimos a Rails que queremos un modelo llamado Article, que
contenga un atributo title de tipo cadena de texto y un atributo text de tipo texto largo.
Esos atributos se aaden automticamente a la tabla articles en la base de datos y se
asocian al modelo Article.
El resultado de ejecutar este comando es que Rails ha creado varios archivos. Por el
momento slo nos
interesanapp/models/article.rb y db/migrate/20140120191729_create_articles.rb (
en tu caso el nombre de este archivo ser ligeramente diferente). Este ltimo se encarga de
crear la estructura de la base de datos, que es lo prximo que vamos a analizar.
El Active Record es lo suficientemente inteligente para asociar automticamente el
nombre de las columnas a los atributos del modelo, lo que significa que no tienes que
declarar los atributos dentro de los modelos de Rails, ya que Active Record lo har por t
automticamente.
TRUCO
5.5. Migraciones
Como hemos visto, el comando rails generate model crea un archivo de migracin de
base de datos en el directoriodb/migrate. Las migraciones son clases de Ruby que estn
diseadas para simplificar la creacin y modificacin de las tablas de la base de datos.
Rails usa comandos rake para ejecutar migraciones, y es posible deshacer una migracin
despus de que ha sido aplicada a la base de datos. Los archivos de migraciones incluyen
un sello de tiempo con la fecha y hora para que siempre sean procesadas en el mismo orden
que fueron creadas.
Si miras el contenido del
archivo db/migrate/20140120191729_create_articles.rb (recuerda que en tu caso el
nombre de este archivo ser ligeramente diferente), esto es lo que encontrars:
class CreateArticles < ActiveRecord::Migration
def change
create_table :articles do |t|
t.string :title
t.text :text
t.timestamps
end
end
end
La migracin de arriba crea un mtodo llamado change que se invoca cuando ejecutas la
migracin. La accin definida en este mtodo es reversible, lo cual significa que Rails sabe
cmo deshacer los cambios realizados en esta migracin en caso que necesites hacerlo ms
adelante.
Cuando ejecutas esta migracin se crea una tabla articles con una columna tipo string y
otra columna tipo text. Tambin crea dos campos de tipo timestamp para que Rails pueda
guarda la fecha y hora en la que los artculos se crean y se modifican.
Puedes encontrar ms informacin sobre las migraciones en el artculo Rails
Database Migrations
En este punto, puedes usar el comando rake para ejecutar la migracin:
NOTA
$ bin/rake db:migrate
Rails ejecutar este comando de migracin y te indicar que ha creado la tabla Articles.
== CreateArticles: migrating ==============================================
====
-- create_table(:articles)
-> 0.0019s
== CreateArticles: migrated (0.0020s) =====================================
====
Como por defecto siempre ests trabajando en el entorno de desarrollo, este comando
se aplica sobre la base de datos definida en la seccin development del
archivo config/database.yml. Si quieres ejecutar migraciones en otro entorno, por
ejemplo en produccin, debes indicarlo en forma explcita cuando invoques el
comando: rake db:migrate RAILS_ENV=production.
NOTA
@article.save
redirect_to @article
end
Lo que est sucediendo ahora es que cada modelo Rails se inicializa con sus respectivos
atributos, que se asocian automticamente con las columnas correspondientes de la base de
datos. La primera lnea del cdigo anterior hace exactamente eso (recuerda
que params[:article] contiene los atributos que nos interesan).
Despus, @article.save se encarga de guardar el modelo en la base de datos. Por ltimo,
redirigimos al usuario a la accin show, que definiremos ms adelante.
Como veremos despus, @article.save devuelve una variable booleana que indica
si el modelo fue guardado o no.
Si recargas de nuevo la pgina http://localhost:3000/articles/new sers casi capaz de crear
un nuevo artculo. Si lo pruebas, vers que se muestra este mensaje de error:
TRUCO
@article.save
redirect_to @article
end
private
def article_params
params.require(:article).permit(:title, :text)
end
El mtodo permit es lo que nos permite aceptar tanto el title como el text en la accin.
Observa que def article_params es un mtodo privado. Esta estrategia impide que
un atacante pueda establecer los atributos del modelo manipulando el hash que se pasa al
modelo. Para ms informacin al respecto, consulta este artculo sobre los Strong
Parameters.
NOTA
Prefix Verb
article GET
URI Pattern
Controller#Action
/articles/:id(.:format)
articles#show
...
La sintaxis :id de la ruta indica a Rails que esta ruta espera un parmetro llamado :id, que
en este caso ser el atributo id del artculo que se quiere ver. Como hicimos anteriormente,
es necesario aadir una nueva accin en el
archivo app/controllers/articles_controller.rb y tambin hay que crear su vista
correspondiente.
def show
@article = Article.find(params[:id])
end
Un par de cosas que debes tener en cuenta: usamos Article.find para encontrar el artculo
que nos interesa, pasndole el valor params[:id] para obtener el
parmetro :id directamente de la peticin. Tambin usamos una variable de instancia (con
el prefijo @) para guardar una referencia al objeto del artculo. Hacemos eso porque Rails
pasa automticamente todas las variables de instancia a la vista.
Ahora, crea un nuevo archivo app/view/articles/show.html.erb con el siguiente
contenido:
<p>
<strong>Title:</strong>
<%= @article.title %>
</p>
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
Con estos cambios, ya deberamos poder crear nuevos artculos. Para ello,
visita http://localhost:3000/posts/new y prubalo.
Prefix Verb
articles GET
URI Pattern
Controller#Action
/articles(.:format)
articles#index
...
<table>
<tr>
<th>Title</th>
<th>Text</th>
</tr>
El mtodo link_to es uno de los helpers que incluye Rails para las vistas. Este mtodo
crea un enlace utilizando el texto y la ruta indicados, que en este caso ser la ruta articles.
Vamos a agregar enlaces a las otras vistas, empezando por aadir el enlace "New
Article" en la vistaapp/views/articles/index.html.erb justo por encima de la
etiqueta <table>:
<%= link_to 'New article', new_article_path %>
Este enlace te permite acceder directamente al formulario para crear nuevos artculos.
Aade tambin un enlace enapp/views/articles/new.html.erb, justo debajo del
formulario, para volver a la portada del sitio:
<%= form_for :article, url: articles_path do |f| %>
...
<% end %>
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
Aunque el archivo est vaco, fjate que la clase hereda de ActiveRecord::Base. El Active
Record aade de esta manera muchas funcionalidades a tus modelos de Rails. Entre otras,
incluye un CRUD bsico, validacin de datos, bsqueda de informacin y la posibilidad de
relacionar modelos entre s.
Rails incluye por ejemplo mtodos que te permiten validar la informacin que envas a los
modelos. Para definir esta validacin, abre el archivo app/models/article.rb y aade lo
siguiente:
class Article < ActiveRecord::Base
validates :title, presence: true,
length: { minimum: 5 }
end
Estos cambios aseguran que que todos los artculos tengan un ttulo de al menos cinco
caracteres de longitud. Rails puede validar diferentes caractersticas de los modelos, como
si incluyen una determinada columna, si su valor es nico en la base de datos, su formato, y
si existen o no objetos relacionados. Las validaciones se explican con detalle en el
artculo Active Record Validations.
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render 'new'
end
end
private
def article_params
params.require(:article).permit(:title, :text)
end
la que se envi el formulario, mientras que redirect_to le dice al navegador que realice
otra peticin.
Si recargas la pgina http://localhost:3000/articles/new y tratas de guardar un artculo sin
ttulo, Rails te mostrar el mismo formulario vaco, lo cual no es muy til. Lo que debemos
hacer es mostrar al usuario qu errores se han producido. Para ello, modifica el
archivo app/views/articles/new.html.erb para que compruebe si existen errores:
<%= form_for :article, url: articles_path do |f| %>
<% if @article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@article.errors.count, "error") %> prohibited
this article from being saved:</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
En este cdigo estn sucediendo varias cosas. Primero comprobamos si existen errores con
el mtodo@article.errors.any?. Si existen, mostramos una lista con todos los errores
obtenidos mediante@article.errors.full_messages.
El helper pluralize es uno de los helpers includos en Rails y que acepta como
argumentos un nmero y una cadena de texto. Si el nmero pasado es mayor que 1, la
cadena de texto se convierte automticamente en plural..
El motivo por el que aadimos @article = Article.new en el
controlador ArticlesController es porque si no, @articletendra un valor nil en la vista.
As que al ejecutar @article.errors.any? se mostrara un error.
Rails encierra automticamente con un <div class="field_with_errors"> a los campos
de formulario que contienen errores. As que slo tienes que definir los estilos CSS
correspondientes para hacer que los mensajes de error destaquen lo suficiente.
Ahora s vers un mensaje de error cuando trates de guardar un artculo sin ttulo en la
pginahttp://localhost:3000/articles/new.
La vista contendr un formulario similar al que hemos usado para crear nuevos artculos.
Para ello, crea el archivoapp/views/articles/edit.html.erb con el siguiente contenido:
<h1>Editing article</h1>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
En esta ocasin el formulario apunta a la accin update, que todava no hemos creado. La
opcin :method => :patch le dice a Rails que queremos enviar este formulario mediante
el mtodo PATCH de HTTP que, segn el protocolo REST, es el que se debe utilizar al
actualizar recursos.
El primer parmetro de form_for puede ser un objeto, por ejemplo @article, que se utiliza
para rellenar los campos del formulario. Si pasas un smbolo (ejemplo :article) cuyo
nombre sea idntico al de una variable de instancia (@article) el funcionamiento es el
mismo. Esto es precisamente lo que est pasando en este ejemplo. Consulta
la documentacin de form_for para conocer ms detalles.
A continuacin, crea la accin update en el
archivo app/controllers/articles_controller.rb:
def update
@article = Article.find(params[:id])
if @article.update(article_params)
redirect_to @article
else
render 'edit'
end
end
private
def article_params
params.require(:article).permit(:title, :text)
end
El nuevo mtodo update se usa al actualizar un registro que ya existe, y acepta como
argumento un hash que contiene los atributos que deseas actualizar. Como hicimos
anteriormente, si hay un error actualizando el artculo queremos volver a mostrar el
formulario al usuario. Para ello se reutiliza el mtodo article_params definido
anteriormente para la accin create.
No es necesario pasar todos los atributos a update. Por ejemplo, si
ejecutaras @article.update(title: 'A new title') Rails solo actualizara el
atributo title sin tocar los otros atributos.
Por ltimo, queremos mostrar un enlace a la accin edit en la lista de todos los artculos.
As que modifica la vistaapp/views/articles/index.html.erb para aadir un nuevo
enlace:
TRUCO
<table>
<tr>
<th>Title</th>
<th>Text</th>
<th colspan="2"></th>
</tr>
<div id="error_explanation">
<h2><%= pluralize(@article.errors.count, "error") %> prohibited
this article from being saved:</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Prefix Verb
URI Pattern
DELETE /articles/:id(.:format)
Controller#Action
articles#destroy
...
El mtodo deletees el que se debe usar para eliminar recursos de la aplicacin. Si esta ruta
siguiera el formato GETtradicional, los usuarios maliciosos podran crear enlaces como el
siguiente:
Para evitarlo se utiliza el mtodo DELETE de HTTP mediante la ruta que est asociada con la
accin destroy del archivoapp/controllers/articles_controller.rb. Como esta
accin no existe todava, crala con el siguiente contenido:
def destroy
@article = Article.find(params[:id])
@article.destroy
redirect_to articles_path
end
Puedes invocar el mtodo destroy en cualquier objeto Active Record para eliminarlo de la
base de datos. Como despus del borrado de informacin se redirige al usuario a la
accin index, no es necesario crear una vista para esta accin destroy.
Finalmente, agrega un enlace a la plantilla de la
accin index (app/views/articles/index.html.erb) para completar todo.
<h1>Listing Articles</h1>
<%= link_to 'New article', new_article_path %>
<table>
<tr>
<th>Title</th>
<th>Text</th>
<th colspan="3"></th>
</tr>
En esta plantilla se utiliza link_to de una manera diferente. El nombre de la ruta se pasa
como segundo argumento y despus se indican las opciones mediante otro argumento. Las
opciones :method y :data-confirm se utilizan como atributos HTML5 para que cuando se
pinche sobre el enlace Rails muestre un mensaje de confirmacin al usuario antes de borrar
la informacin.
Este comportamiento es posible gracias al archivo JavaScript llamado jquery_ujs, que se
incluye automticamente en el layout de la aplicacin
(app/views/layouts/application.html.erb) que se cre al generar la aplicacin Rails.
Si no se incluye este archivo, el mensaje de confirmacin no se muestra.
Figura 5.10 Ventana JavaScript con un mensaje de confirmacin para borrar artculos
File
Purpose
db/migrate/20140120201010_create_comments.rb
app/models/comment.rb
El modelo Comment
test/models/comment_test.rb
test/fixtures/comments.yml
end
t.timestamps
end
end
end
La lnea t.references crea una columna de tipo clave fornea para establecer la
relacin entre los dos modelos. Adems se crea un ndice para esta columna.
Como ya tenemos todo preparado, ejecuta el siguiente comando:
$ bin/rake db:migrate
Rails es lo bastante inteligente como para ejecutar solamente las migraciones que
todava no se han ejecutado en la base de datos que se est utilizando. As que el
resultado de ejecutar el comando ser:
Gracias a estas dos declaraciones (belongs_to y has_many), Rails puede hacer casi
todo el trabajo automticamente. Si por ejemplo tienes una variable de instancia
llamada @article que contiene un artculo, puedes obtener todos sus comentarios
mediante la isntruccin @article.comments.
Consulta el artculo Active Record Associations para obtener ms
informacin sobre las asociaciones.
NOTA
Esta configuracin crea la ruta comments dentro de la ruta articles que definimos
anteriormente. Esta es otra forma de establecer la relacin entre los dos modelos.
NOTA
Archivo/Directorio
Propsito
app/controllers/comments_controller.rb
El controlador Comments
Archivo/Directorio
Propsito
app/views/comments/
test/controllers/comments_controller_test.rb
app/helpers/comments_helper.rb
test/helpers/comments_helper_test.rb
app/assets/javascripts/comment.js.coffee
app/assets/stylesheets/comment.css.scss
</p>
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br>
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Este cdigo aade un formulario en la pgina show de los artculos para poder
crear nuevos comentarios llamando a la accin create del
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
end
Este controlador es un poco ms complejo del que creamos para los artculos.
Esta es una de las consecuencias de anidar relaciones. Cada peticin relacionada
con un comentario debe contener una referencia al artculo con el que est
relacionado. Por eso tenemos que buscar primero el modelo Article que est
relacionado con el comentario.
Adems, la accin utiliza algunos de los mtodos disponibles para las relaciones.
As por ejemplo se utiliza el mtodocreate sobre @article.comments para crear y
guardar un comentario. Esto hace que el comentario est automticamente
relacionado con este artculo especfico.
Despus de crear el nuevo comentario, se redirige al usuario de nuevo a la pgina
que meustra el artculo original mediante el helper article_path(@article). Como
acabamos de ver, este helper llama a la accin show del
controladorArticlesController, que a su vez renderiza la plantilla show.html.erb.
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<h2>Comments</h2>
<% @article.comments.each do |comment| %>
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br>
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Captulo 7. Refactorizacin
La aplicacin ya permite crear artculos y comentarios, pero si echas un vistazo al
archivoapp/views/articles/show.html.erb vers que la plantilla es muy larga y su
cdigo es un poco catico. Para limpiar el cdigo podemos hacer uso de
los parciales.
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
Then you can change app/views/articles/show.html.erb to look like the follow
ing:
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<h2>Comments</h2>
<%= render @article.comments %>
<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br>
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
itera sobre @article.comments, asigna cada comentario a una variable local con el
mismo nombre que el parcial (en este caso, comment).
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<h2>Comments</h2>
<%= render @article.comments %>
<h2>Add a comment:</h2>
<%= render "comments/form" %>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<p>
<%= link_to 'Destroy Comment', [comment.article, comment],
method: :delete,
data: { confirm: 'Are you sure?' } %>
</p>
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
redirect_to article_path(@article)
end
def destroy
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
@comment.destroy
redirect_to article_path(@article)
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
end
Captulo 9. Seguridad
9.1. Autenticacin bsica
Si publicaras ahora tu aplicacin Rails, cualquier persona podra aadir, editar y
borrar artculos y comentarios. Obviamente Rails incluye algunas opciones de
seguridad para evitar esto. Una de ellas es la autenticacin basada en HTTP.
La clave consiste en proteger el acceso a varias de las acciones definidas en el
controlador ArticlesController. Si el usuario no est autenticado, no podr
acceder a esas acciones. Para ello utilizaremos el
mtodohttp_basic_authenticate_with de Rails.
La configuracin de la autenticacin en este caso consiste en indicar al principio
del controlador ArticlesControllerque quereos proteger todas las acciones
salvao index y show:
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
# ...
Otra restriccin adicional consiste en evitar que los usuarios puedan borrar
comentarios. Para ello, aade lo siguiente
en CommentsController (archivo app/controllers/comments_controller.rb):
class CommentsController < ApplicationController
def create
@article = Article.find(params[:article_id])
...
end
# ...
Rails tambin incluye una completa ayuda que puedes consultar mediante la
utilidad rake de la lnea de comandos:
Ejecuta rake doc:guides para obtener una copia completa de las guas de
Rails en el directorio doc/guides de tu aplicacin. Despus slo tienes que
abrir el archivo doc/guides/index.html en tu navegador favorito.