View
8
Download
0
Category
Preview:
Citation preview
Introducción a rails 3!!Rails es un framework de desarrollo de aplicaciones web escrito en el lenguaje Ruby. Está diseñado para hacer la programación de aplicaciones web más fácil al hacer suposiciones acerca de lo que necesita cada desarrollador para empezar. !Se permite escribir menos código en contraste de muchos otros lenguajes y frameworks. Desarrolladores experimentados de Rails también informan que hace que el desarrollo de aplicaciones web más divertida.!Una cosa muy importante al utilizar rails para el desarrollo es que se basa en el principio de Convención sobre configuración, por lo cual es muy importante cumplir con los estándares.!!Instalación de rails!!- Mac OS X y Linux: Para estas dos plataformas se recomienda el uso de RVM para tener
multiples versiones de ruby en un mismo equipo, para esto simplemente utilizamos el comando en terminal: user$ \curl -sSL https://get.rvm.io | sudo bash -s stable Para más información, favor de consultar el sitio oficial http://rvm.io/rvm/install !
- Windows: En el caso de Windows se recomienda el utilizar “RubyInstaller” http://railsinstaller.org/en que es un ejecutable.!!
Creando una aplicación de ejemplo!!Antes de empezar, debemos revisar si está instalado ruby y rails para poder comenzar, para esto corremos el comando en terminal que nos dará nuestra versión de ruby.!!$ ruby -‐v !En caso de recibir el mensaje de que no existe ruby, favor de proceder a su instalación.!!Una vez hecho esto, podemos comenzar.!!El primer paso es instalar rails, lo cual se logra con el siguiente comando:!!$ gem install rails !Una vez finalizado este proceso procedemos a crear nuestra aplicación.!!$ rails new blog -‐d mysql !Nota: En caso de no indicarse “-d mysql” se usará sqlite3 por default y “blog” es nuestro nombre de proyecto.!Nota2: Si se tienen multiples versiones de rails, se puede especificar de la siguiente manera “rails _3.2.9_ new myapp” .!
Lo anterior nos creará una estructura como esta:!
Con lo cual nuestro proyecto estará creado y casi listo para iniciar.!A continuación tenemos que modificar nuestro archivo de base de datos, para lo cual abrimos el archivo “blog/config/database.yml” que se verá algo así.!
Ahora, sólo nos falta que modifiquemos los valores para que correspondan con los de nuestro sistema.!
Una vez modificado nuestro archivo de base de datos, procedemos a desde la terminal ingresar a la carpeta de nuestro proyecto y ya podemos iniciarlo con el comando.!!$ rails server !Lo cual iniciará nuestra aplicación en un servidor incluido con rails y nos colocará en el puerto 3000 nuestra web para que probemos.!
Obviamente nuestra aplicación aún no hace nada, pero por lo menos ya tenemos nuestra página de inicio.!!Ahora es momento de revisar todas nuestras carpetas y archivos para ver que encontraremos en cada uno.!!Carpeta/Archivo Propósito
app/ Contiene los controladores, modelos, vistas, helpers, mailers y assets para nuestra aplicación. La mayoría del trabajo se hace aquí.
bin/ Contiene los scripts de rails que inician la app y pueden contener otros scripts que se usen para deplorar o correr la app.
config/ Configura tu aplicación, ya sea de rutas, bases de datos, etc.
config.ru Configuración para servidores basados en Rack utilizados para iniciar la aplicación
db/ Contiene tu esquema de base de datos, así como las migraciones
!Bueno, pues ahora el siguen paso es cambiar nuestra pantalla de inicio, para lo cual vamos a crear un nuevo controlador con una acción. Para esto, en nuestra terminal ejecutamos el comando:!!$ rails generate controller welcome index !Con esto rails creará muchos archivos y agregará una ruta al archivo de rutas:!!create app/controllers/welcome_controller.rb route get 'welcome/index' invoke erb create app/views/welcome create app/views/welcome/index.html.erb invoke test_unit create test/controllers/welcome_controller_test.rb invoke helper create app/helpers/welcome_helper.rb invoke test_unit create test/helpers/welcome_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/welcome.js.coffee invoke scss create app/assets/stylesheets/welcome.css.scss !Los que por ahora nos interesan son “app/controllers/welcome_controller.rb” y “app/views/welcome/index.html.erb” que contienen nuestro controlador y nuestra vista respectivamente.!!
Gemfile y Gemfile.lock Estos archivos nos permiten especificar que gemas queremos incluir en nuestra aplicación rails.
lib/ Aqui se colocan modulos apra la aplicación.
log/ Contiene los archivos de log.
public/ Esta debe ser la única carpeta visible por el mundo, contiene archivos estáticos y los assets compilados.
Rakefile Localiza y carga las tareas que pueden ser ejecutadas desde la linea de comandos. Las definiciones de tareas son definidas agraves de componentes de Rails (No se debe modificar).
README.rdoc Breve documentación sobre la aplicación.
test/ Destinada para el uso de pruebas.
tmp/ Contiene archivos temporales como sesiones entre otros.
vendor/ Todo el código de terceros se include aquí.
Carpeta/Archivo Propósito
Abrimos nuestra vista “app/views/welcome/index.html.erb” y modifiquemos nuestro código para tener nuestro hello rails.!!<h1>Hello, Rails!</h1> !Y ahora.!!Configuramos nuestra página de inicio!Para lo cual abrimos nuestro archivo de rutas “config/routes.rb”. Y veremos algo como esto:!!Rails.application.routes.draw do get 'welcome/index' # The priority is based upon order of creation: # first created -‐> highest priority. # # You can have the root of your site routed with "root" # root 'welcome#index' # # ... !Ahora simplemente agregamos esta linea con la que indicamos cual es nuestra ruta por default:!!root 'welcome#index' !Lo anterior le dice a Rails que relacione el root de la aplicación a la acción “index” del controlador “welcome” y así mismo get 'welcome/index' le dice a Rails que relacione http://localhost:3000/welcome/index a la acción “index” del controlador “welcome”. Por último nos resta borrar o re-nombrar el archivo “public/index.html” ya que Rails toma este por default.!Y además tenemos que crear nuestra base de datos de desarrollo, para lo cual basta con ejecutar el comando:!!rake db:create !Una vez echo esto, podemos iniciar de nuevo nuestra aplicación para ver el resultado.!
Para la siguiente parte, vamos a comenzar a agregar, verdadera funcionalidad.!!Primero que nada empezaremos agregando un “recurso” a nuestro archivo de rutas, un recurso es el termino usado para hacer referencia a una colección de objetos similares, como artículos, personas o animales. Sobre los cuales se pueden ejecutar las operaciones CRUD (create, read, update and destroy).!Ahora en nuestro archivo de rutas agregamos la siguiente linea:!! resources :articles !Con lo cual se nos crearan algunas URLs, para ver las urls que tenemos, corremos el comando:!! rake routes !Lo cual nos mostrará algo similar a esto:!!$ rake routes articles GET /articles(.:format) articles#index POST /articles(.:format) articles#create new_article GET /articles/new(.:format) articles#new edit_article GET /articles/:id/edit(.:format) articles#edit article GET /articles/:id(.:format) articles#show PUT /articles/:id(.:format) articles#update DELETE /articles/:id(.:format) articles#destroy welcome_index GET /welcome/index(.:format) welcome#index root / welcome#index !Ahora, si intentamos acceder cualquier ruta de nuestro recurso, nos saldrán errores, ya que no existen ni los controladores, ni las acciones y tampoco las vistas necesarias.!
Pero esto es correcto por las razones antes mencionadas.!!
Ahora, para continuar vamos a crear nuestro controlador para el recurso de “articles”:!!!$ rails g controller articles !!Con esto se generará nuestro controlador “app/controllers/articles_controller.rb” el ciar abrimos para empezar a trabajar y veremos algo así:!!class ArticlesController < ApplicationController end !Un “controller” no es otra cosa que una clase que hereda de “ApplicationController”, y es aquí donde trabajaremos con nuestros métodos CRUD.!!Ahora, si refrescamos la página veremos que el error cambia:!
Indicándonos ahora, que se desconoce la acción, ya que claro, no la hemos creado.!Lo siguiente es definir esta acción, para lo cual en nuestro controller simplemente agregamos dentro de la clase:!!def new end !Y si de nuevo refrescamos, veremos que el error cambia de nuevo:!
!Básicamente esto nos dice que no se encuentra la vista correspondiente. que para este caso es “articles/new, application/new”, como podemos ver busca en dos directorios, esto es porque el primero es el del recurso y el segundo es el de la clase padre, es decir “ApplicationController”. Y !“formats:[:html]” simplemente nos dice que espera un html que es el formato por default aunque puede ser reemplazado por otros como “json”.!!Ahora, para reparar esto, vamos a usar el template más simple, que sería “app/views/articles/new.html.erb”, hay que notar la importancia de la extensión, ya que la primera extensión es el formato, y la segunda es el “handler” que será utilizado. Rails intenta encontrar un template llamado “articles/new” dentro de “app/views” para la aplicación. El formato para este template sólo puede ser html y el handler debe ser uno de erg, builder o coffee. !!Como queremos crear una nueva forma HTML, usaremos el lenguaje ERB. Por lo cual el archivo debe ser nombrado“app/views/articles/new.html.erb” y necesita estar en dicho directorio. Y simplemente agregamos esta linea y refrescamos.!!<h1>New Article</h1>
El siguiente paso es crear nuestra primera forma, para lo cual utilizaremos un “form builder” que nos proporciona rails mediante un método helper llamado “form_for”.!!!<%= form_for :article do |f| %> <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 %>
Si refrescamos la página veremos que ahora tenemos un formulario.!Y aquí tenemos nuestro html.!!<form
method="post" action="/articles/new" accept-‐charset="UTF-‐8"><div style="margin:0;padding:0;display:inline"><input type="hidden" value="✓" name="utf8"><input type="hidden" value="RePzfBEklbIwioNftzNUkPVfGhTVd/FVxXun+UeEcc4=" name="authenticity_token"></div> <p> <label for="article_title">Title</label><br> <input type="text" size="30" name="article[title]" id="article_title"> </p> <p> <label for="article_text">Text</label><br> <textarea rows="20" name="article[text]" id="article_text" cols="40"></textarea> </p> <p> <input type="submit" value="Save Article" name="commit"> </p> </form> !Cuando llamamos “form_for”, le pasamos un objeto identificador para la forma, en este caos el símbolo “:article”. Lo cual le dice al form_for para qué es este formulario. Dentro del bloque para este método, el FormBuilder representado por “f” is utilizado para construir dos labels y dos campos de texto, así como un botón de submit.!Sin embargo como vemos en el HTML la url de acción no es la correcta según el estándar REST ya que debería hacer referencia a “/articles” utilizando el método “POST”.!Para solucionar esto, simplemente hacemos este cambio:!!<%= form_for :article, url: articles_path do |f| %>
Esta URL nos la da rake routes como lo vimos anteriormente:!!$ rake routes articles GET /articles(.:format) articles#index POST /articles(.:format) articles#create new_article GET /articles/new(.:format) articles#new edit_article GET /articles/:id/edit(.:format) articles#edit article GET /articles/:id(.:format) articles#show PUT /articles/:id(.:format) articles#update DELETE /articles/:id(.:format) articles#destroy welcome_index GET /welcome/index(.:format) welcome#index root / welcome#index !Ahora vamos a crear nuestra acción que responderá a esta URL que es el create.!!def create render json: params[:article].inspect end !Para evitar el error de missing template, agregamos la segunda linea, con lo cual vamos a ver un json con los parámetros enviados al darle click al botón submit.!!{"title"=>"qwqwer", “text"=>"qwerqwer"} !Para continuar vamos a crear un modelo para los artículos.!!Creando el model Article!!Los models en Rails utilizan nombres singulares que corresponden a los nombres de las tablas en la base de datos. Rails nos proporciona un generador para crear dichos modelos que es la manera más común de hacerlo. Para crear un nuevo modelo corremos en terminal:!!$ rails generate model Article title:string text:text !Con esto, Rails crea varios archivos, de los cuales sólo nos interesan “app/models/article.rb” y “db/migrate/20140602231306_create_articles.rb”, el nombre del segundo archivo puede ser un poco diferente. El segundo archivo es responsable de crear la estructura en la base de datos.!!Si abrimos nuestra migración db/migrate/20140602231306_create_articles.rb veremos algo así:!!class CreateArticles < ActiveRecord::Migration def change create_table :articles do |t| t.string :title t.text :text t.timestamps end end end
Lo cual crea un método llamado “change” el cual se ejecutará al correr esta migración, que como podemos observar va a crearnos la tabla “articles” con los campos id(por default), titulo, texto y timestamps para fechas de creación y modificación.!Ahora ejecutamos el comando:!!$ rake db:migrate !Que nos regresará un mensaje.!!== CreateArticles: migrating ================================================== -‐-‐ create_table(:articles) -‐> 0.0019s == CreateArticles: migrated (0.0020s) ========================================= !Nota: Por default esto afecta a la base de datos de desarrollo, si queremos que tome efecto en producción, debemos indicarlo “rake db:migrate RAILS_ENV=production”.!
Una vez que ya tenemos nuestra tabla creada, procedamos guardar el artículo.!!!Abrimos “app/controllers/articles_controller.rb” y modificamos nuestro método create.!!def create @article = Article.new(params[:article]) respond_to do |format| if @article.save format.html { redirect_to @article, notice: 'Changes Saved.' } format.json { render json: @article, status: :created, location: @article } else format.html { render action: "new" } format.json { render json: @article.errors, status: :unprocessable_entity } end end end !!!!
Si refrescamos la página y damos click al botón del formulario de nuestro artículo veremos que se guarda pero nos muestra el error:!
Esto ya debemos reconocerlo y se debe a que no existe nuestro método ni nuestra vista, así que vayamos a resolver ambos.!!Primero editamos nuestro controller para agregar la acción “show”:!!def show @article = Article.find(params[:id]) respond_to do |format| format.html # show.html.erb format.json { render json: @article } end end !Y creamos nuestro archivo de vista “app/views/articles/show.html.erb” con el siguiente contenido:!!<p> <strong>Title:</strong> <%= @article.title %> </p> <p> <strong>Text:</strong> <%= @article.text %> </p> !Con esto ya podemos actualizar nuestra página para ver los resultados.!!!
Cabe mencionar como nota, que el “respond_to” nos permite responder diferente dependiendo del formato que solicitemos ya que si por ejemplo al final de la URL agregamos un .json veremos lo siguiente:!
Que como podemos ver es un objeto en dicho formato.!!Creando el index!!Como normalmente sucede, necesitaremos un listado de nuestros artículos, para esto utilizamos un index, así que a crearlo.!!Recordemos que la ruta es:!!articles GET /articles(.:format) articles#index !Por lo tanto vamos a añadir el método index a nuestro controller:!!def index @articles = Article.all respond_to do |format| format.html # index.html.erb format.json { render json: @articles } end end !Con esto le decimos a nuestro modelo que nos traiga todos los artículos que encuentre en nuestra base de datos.!Ahora creamos nuestro “app/views/articles/index.html.erb” para mostrar el listado:!!<h1>Listing articles</h1> <table> <tr> <th>Title</th> <th>Text</th> </tr> <% @articles.each do |article| %> <tr> <td><%= article.title %></td> <td><%= article.text %></td> </tr> <% end %> </table>
Con lo anterior si vamos a http://localhost:3000/articles veremos un listado de nuestros artículos.!
Obviamente no vamos a estar cambiando la URL manualmente, así que!!Agreguemos unos enlaces!!Abramos nuestra vista por default “app/views/welcome/index.html.erb” y agreguemos el primer enlace:!!<h1>Hello, Rails!</h1> <%= link_to 'My Blog', controller: 'articles' %> !El método “link_to” es un helper que nos ayuda a generar enlaces. Si queremos probarlo podemos hacerlo “http://localhost:3000/“ y damos click al enlace generado.!!Ahora modifiquemos “app/views/articles/index.html.erb” para agregar lo siguiente:!!<%= link_to 'New article', new_article_path %> !Y actualizamos nuestra tabla.!!<% @articles.each do |article| %> <tr> <td><%= article.title %></td> <td><%= article.text %></td> <td><%= link_to 'Show', article_path(article) %></td> <td><%= link_to 'Edit', edit_article_path(article) %></td> </tr> <% end %> !Y por su puesto modificamos nuestro “app/views/articles/new.html.erb” y al final del documento agregamos el link, que nos quedará similar a:!!<%= form_for :article, url: articles_path do |f| %> ... <% end %> <%= link_to 'Back', articles_path %> !
Y por último “app/views/articles/show.html”!!<%= link_to 'Back', articles_path %> !Ahora podemos probar todos nuestros enlaces. Y pasemos a lo siguiente.!!Agregar validaciones!!Antes de esto, modifiquemos nuestro controlador y agreguemos la siguiente linea en el método “create”:!!@article = Article.new !Más adelante veremos para qué es esto.!!!Para hacer las validaciones utilizaremos nuestro modelo “app/models/article.rb “.!!!!!Y agregaremos:!!class Article < ActiveRecord::Base validates :title, presence: true, length: { minimum: 5 } end !Con esto nos aseguramos de que exista un título y tenga una longitud mínima de 5.!Esta validaciones corresponden a la clase padre “ActiveRecord” para más detalle “http://guides.rubyonrails.org/active_record_validations.html”!!Si ahora intentamos guardar un artículo que no cumpla estas validaciones veremos que no se guarda, mas sin embargo no nos da ningún mensaje.!Así que editemos nuestro archivo “app/views/articles/new.html.erb":!!<%= 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 %> <%= link_to 'Back', articles_path %> !El código nuevo lo que hace es básicamente preguntar si existen errores “@article.errors.any?”, y en caso de que sea así se muestra una lista de errores con “@article.errors.full_messages”.!!“pluralize” es un helper de rails que toma un número una string como parámetros. En caso que el número se mayo que uno, el string es pluralizado de manera automática.!!Es importante notar que la modificación al método create fue para evitar que sea nulo.!!Ahora, si volvemos a enviar nuestro formulario sin cumplir las validaciones nos mostrará algunos errores.!
Ahora el update!!Lo siguiente es programar el actualizar la información de nuestros artículos, para lo cual necesitaremos nuestro método “edit” en nuestro controlador:!!def edit @article = Article.find(params[:id]) end !Y un nuevo archivo de vista “app/views/articles/edit.html.erb”:!!
<h1>Editing article</h1> <%= form_for :article, url: article_path(@article), method: :put 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 %> <%= link_to 'Back', articles_path %> !!En esta ocasión hemos apuntado el formulario a la acción update mediante el parámetro method: :put, el cual no existe, pero lo haremos en breve.!!def update @article = Article.find(params[:id])
respond_to do |format| if
@article.update_attributes(params[:article]) format.html { redirect_to @article, notice: 'Changes Saved.' } format.json { head :no_content } else format.html { render action: "edit" } format.json { render json: @article.errors, status: :unprocessable_entity } end end end !Con esto como podemos ver, en caso de que se apliquen los cambios seremos re-dirigidos a la URL del artículo que hemos editado.!Ya podemos revisar esta funcionalidad.!!!!!!!!!!!!Eliminando código duplicado!!Como podemos ver, las formas de nuestra acción new y edit, son prácticamente iguales, salvo por la url, así que vamos a remediar esto utilizando algo llamado “partials”.!!Para esto creamos el archivo “app/views/articles/_form.html.erb” y colocamos el siguiente código:!!<%= form_for @article 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 %> !Como podemos ver, simplemente se ha omitido la URL destino, ya que rails es suficientemente inteligente para detectar que URL utilizar para el recurso correspondiente.!!Ahora editamos nuestra vista de new:!!<h1>New article</h1> <%= render 'form' %> <%= link_to 'Back', articles_path %> !Y la de edit:!!<h1>Edit article</h1> <%= render 'form' %> <%= link_to 'Back', articles_path %> !Con esto si refrescamos ambas URLs, veremos que el comportamiento no se ha visto afectado.!!Borrando elementos!!En nuestro controller:!!def destroy @article = Article.find(params[:id]) @article.destroy ! respond_to do |format| format.html { redirect_to articles_url } format.json { head :no_content } end end !Y en nuestro index agregamos a la tabla después de los enlaces de show y edit:!! <td><%= link_to 'Destroy', article, method: :delete, data: { confirm: 'Are you sure?' } %></td> !Con esto si refrescamos la vista, veremos que ahora, podemos eliminar artículos, con lo cual terminamos nuestras operaciones CRUD.!!El segundo modelo!!Como vemos ese es un comportamiento muy simple, así que vamos a generar un segundo modelos para que nuestros artículos puedan tener comentarios.!!!!!!
Primero generamos el modelo:!!$ rails generate model Comment commenter:string body:text article:references !Si revisamos nuestro modelo veremos algo así:!!class Comment < ActiveRecord::Base belongs_to :article attr_accessible :body, :commenter end !Como vemos, a demás de los campos body y commenter, tenemos la linea belongs_to, que nos hace referencia a la asociación entre los modelos para ActiveRecord.!!De igual manera si observamos la migración, veremos esto:!!class CreateComments < ActiveRecord::Migration def change create_table :comments do |t| t.string :commenter t.text :body t.references :article ! t.timestamps end add_index :comments, :article_id end end !Lo cual es bastante entendible.!!Ahora ejecutamos la migración.!!$ rake db:migrate !Y por último agregamos la asociación en nuestro “app/models/article.rb”:!!class Article < ActiveRecord::Base has_many :comments attr_accessible :text, :title validates :title, presence: true, length: { minimum: 5 } end !Con lo anterior, podemos utilizar esta asociación con simplemente hacer @article.comments!!!!
Ahora actualizamos nuestro archivo de rutas:!!resources :articles do resources :comments end !Lo siguiente es generar un controlador:!!$ rails generate controller Comments !En nuestro controlador sólo tendremos dos acciones, una para crear comentarios y otra para eliminarlos.!!Pero primero, actualicemos la vista “app/views/articles/show.html.erb” para permitir a los visitantes agregar comentarios y listar los que ya existan.!!<p> <strong>Title:</strong> <%= @article.title %> </p> <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 %> !<%= link_to 'Back', articles_path %> <%= link_to 'Edit', edit_article_path(@article) %> !!!!!Y agregamos nuestro create en el controller “app/controllers/comments_controller.rb”:!!def create @article = Article.find(params[:article_id]) @comment = @article.comments.create(params[:comment]) redirect_to article_path(@article) end !Con estos cambios, podemos ya agregar comentarios a nuestros artículos.!!!!!!!!!!!!!!!!!!todo esto está muy bien, pero nuestro “app/views/articles/show.html.erb” está creció mucho, así que, lo vamos a limpiar utilizando partials.!!Vamos a crear “app/views/comments/_comment.html.erb” el cual nos servirá para listar los comentarios:!!<p> <strong>Commenter:</strong> <%= comment.commenter %> </p> <p> <strong>Comment:</strong> <%= comment.body %> </p>
Y actualizamos nuestro “app/views/articles/show.html.erb” para que quede algo así:!!<p> <strong>Title:</strong> <%= @article.title %> </p> <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 %> !<%= link_to 'Back', articles_path %> <%= link_to 'Edit', edit_article_path(@article) %> !!Listo, si refrescamos veremos que todo sigue funcionando igual, esto es ya que el método “render” itera sobre la colección @article.comments asignado cada comentario a una variable local en nuestro partial.!!Pero aún no terminamos, así que vamos a mover nuestro formulario.!Creamos “app/views/comments/_form.html.erb” con el siguiente contenido:!!<%= 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 %> !Y nuestro “app/views/articles/show.html.erb” quedaría de la siguiente forma:!!<p> <strong>Title:</strong> <%= @article.title %> </p> <p> <strong>Text:</strong> <%= @article.text %> </p> <h2>Comments</h2> <%= render @article.comments %> <h2>Add a comment:</h2> <%= render "comments/form" %> !<%= link_to 'Back', articles_path %> <%= link_to 'Edit', edit_article_path(@article) %> !Si de nuevo refrescamos nuestra página, veremos que todo funciona igual, y tenemos un código mucho más limpio y legible.!!Borrando comentarios!!Debes en cuando alguien publica un comentario inapropiado o spam que necesita ser eliminado, para esto vamos a actualizar nuestro partial “app/views/comments/_comment.html.erb” y agregamos dicha opción:!!<p> <strong>Commenter:</strong> <%= comment.commenter %> </p> <p> <strong>Comment:</strong> <%= comment.body %> </p> <p> <%= link_to 'Destroy Comment', [comment.article, comment], method: :delete, data: { confirm: 'Are you sure?' } %> </p> !
Este link, nos generará un enlace a la URL “http://localhost:3000/articles/2/comments/1” con el método REST DELETE, así que vamos a actualizar nuestro controller para que contenga este método:!!class CommentsController < ApplicationController def create @article = Article.find(params[:article_id]) @comment = @article.comments.create(params[:comment]) 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 end !Con estos cambios, ya podemos borrar nuestros comentarios.!!Borrando objetos asociados!!Si bien ya podemos borrar artículos y comentarios, actualmente cuando se elimina un artículo no se eliminan los comentarios asociados al mismo, afortunadamente Rails nos va a facilitar las cosas, así que simplemente vamos a actualizar “app/models/article.rb”:!!class Article < ActiveRecord::Base has_many :comments, dependent: :destroy attr_accessible :text, :title validates :title, presence: true, length: { minimum: 5 } end !Y listo, con esto, al borrar nuestros artículos, automáticamente se eliminarán los comentarios asociados al mismo.!!Seguridad!!Rails nos provee una autenticación MUY básica que vamos a utilizar para que sólo los que tengan las credenciales necesarias puedan eliminar comentarios no deseados, para esto vamos a utilizar un autenticación HTTP simple que funciona bien para este caso.!!Vamos a editar nuestro “app/controllers/comments_controller.rb”:!!class CommentsController < ApplicationController http_basic_authenticate_with name: "master", password: "secret", only: :destroy … !!
Con esto, al querer eliminar un comentario, vamos a ver que nos pide una autenticación.!
!!!Y listo, tenemos un pequeño sistema de blog.!!Agregando estilos!!!Como podemos ver, el sitio está muy plano, así que vamos a agregar un poco de estilo.!Abrimos nuestro “app/assets/stylesheets/application.css” que es nuestro archivo principal de estilos, y aquí, vamos a escribir un pequeño css:!!body { background-‐color: #FFFFFF; color: #333333; font-‐family: "Helvetica Neue",Helvetica,Arial,sans-‐serif; font-‐size: 14px; line-‐height: 1.42857; } body { margin: auto; width: 970px; } table{ width: 100%; text-‐align: left; } td{ border-‐top: 1px solid #DDDDDD; } !
Con estos pequeños cambios, podemos tener un sitio un poco más presentable.!!Un poco de javascript!!Bueno, la mayoría de sitios utilizan js para alguna funcionalidad, si nosotros queremos hacer lo mismo, simplemente podemos hacerlo, para esto editamos nuestro “app/assets/javascripts/application.js” donde crearemos un “reloj”:!!function updateClock ( ) { var currentTime = new Date ( ); ! var currentHours = currentTime.getHours ( ); var currentMinutes = currentTime.getMinutes ( ); var currentSeconds = currentTime.getSeconds ( ); ! // Pad the minutes and seconds with leading zeros, if required currentMinutes = ( currentMinutes < 10 ? "0" : "" ) + currentMinutes; currentSeconds = ( currentSeconds < 10 ? "0" : "" ) + currentSeconds; ! // Choose either "AM" or "PM" as appropriate var timeOfDay = ( currentHours < 12 ) ? "AM" : "PM"; ! // Convert the hours component to 12-‐hour format if needed currentHours = ( currentHours > 12 ) ? currentHours -‐ 12 : currentHours; ! // Convert an hours component of "0" to "12" currentHours = ( currentHours == 0 ) ? 12 : currentHours; ! // Compose the string for display var currentTimeString = currentHours + ":" + currentMinutes + ":" + currentSeconds + " " + timeOfDay; ! // Update the time display document.getElementById("clock").firstChild.nodeValue = currentTimeString; } !Lo siguiente es editar nuestro layout general “app/views/layouts/application.html.erb”:!!<!DOCTYPE html><html><head> <title>Blog</title> <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %></head><body onload="updateClock(); setInterval('updateClock()', 1000 )"><span id="clock"> </span><%= yield %>!</body></html>
Si ahora actualizamos nuestro blog, tendremos un pequeño reloj que nos dará la hora en la página.!!Con lo cual damos por terminado este tutorial.
Recommended