Creación de las vistas

Por el momento no hemos tocado el frontend, dudo que sea de tu agrado el tener una aplicación que no puedes ver; hoy trabajaremos en las vistas, para dejarlas presentables a los ojos de otras personas.

Utilizaré Semantic UI puro, no haré modificaciones a los estilos de nuestro sitio, sin embargo eres más que bienvenido de hacerlo si así deseas.

Instalación de Semantic UI

Hay varios métodos para instalarlo, yo usaré el más simple: una gema. Abre el archivo Gemfile y añade la siguiente línea:

gem "semantic-ui-sass", github: "doabit/semantic-ui-sass"

Y como estás acostumbrado, corre bundle:

$ bundle

Una vez termine el proceso, debemos cambiar la extensión de nuestro archivo “app/assets/stylesheets/application.css” a “app/assets/stylesheets/application.scss”. Posteriormente, abre el archivo, elimina todo su contenido y escribe lo siguiente en su lugar:

@import "semantic-ui";

Felicidades, si reinicias el servidor los assets serán re compilados, ahora añadiremos avatares a los usuarios de una manera rápida y continuaremos.

Entra Paperclip

Con la gema Paperclip podremos permitir que nuestros usuarios suban imagenes que sirvan como sus avatars. Su instalación es muy simple, en el archivo Gemfile escribe:

gem "paperclip", "~> 5.0.0"

Posteriormente, corre bundle:

$ bundle

Es tiempo de reiniciar el servidor y añadir los avatares para nuestros usuarios, desde la terminal escribe:

$ rails generate paperclip user avatar

De esta forma generaremos una columna avatar en nuestra tabla de usuarios. Hora de migrar:

$ rails db:migrate

Ahora, en nuestro modelo de usuario debemos añadir un par de lineas que se explican bastante bien por si solas:

has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/default_avatar.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
validates_with AttachmentSizeValidator, attributes: :avatar, less_than: 1.megabytes
  1. Nos aseguramos de que el usuario suba un avatar, si no lo hace asignamos uno por defecto.
  2. Validamos el contenido adjunto.
  3. Validamos el tamaño del avatar.

Ahora, en el archivo “app/controllers/application_controller.rb” debemos permitir que los usuarios suban un avatar, así que justo debajo de “protect_from_forgery with: :exception” añade:

before_filter :configure_permitted_parameters, if: :devise_controller?

  protected

    def configure_permitted_parameters
      devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password) }
      devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:email, :password, :current_password, :avatar) }
end

Como puedes ver, son todas columnas de nuestra tabla de usuarios. Ahora que terminamos con el usuario por el momento, trabajaremos en las vistas.

Vistas de Usuario

  • app/views/users/registrations/new.html.erb:

  • app/views/users/registrations/edit.html.erb:

  • app/views/users/sessions/new.html.erb:

Todo cortesía de Semantic UI, puedes echar un vistazo a su documentación para saber más al respecto.

Partials

Los partials son vistas que usualmente utilizamos en varias vistas al tiempo, también son usadas para separar funciones, bloques grandes de código, etc.

  • app/views/partials/_menu.html.erb:

  • app/views/partials/_notification.html.erb:

Si notaste, usamos el helper que mencionamos un par de capítulos atrás: current_user. Puedes mostrar cualquier dato del usuario haciendo uso de este, por ejemplo current_user.email mostrará el email del usuario de la sesión actual.

Ahora debemos incluir los archivos que acabamos de crear, abre app/views/layouts/application.html.erb y justo debajo de la etiqueta de inicio del body añade las siguientes lineas:

<%= render "partials/menu" %>
<%= render "partials/notification" %>

Con esto le indicamos a Rails que busque los archivos y los inserte en el documento cada vez que realizamos una petición. Rails usa direcciones absolutas y relativas, si deseas usar un archivo que esta en otro directorio probablemente quieras usar la primera.

Vistas de Facts

  • app/views/facts/index.html.erb:

Podrás notar que hacemos uso nuevamente de “current_user”, para asegurarnos que solo los usuarios con una sesión activa puedan ver el botón para crear un nuevo fact. También verás que iteramos sobre los Facts en nuestra tabla, es por esto que en nuestro método index usamos @facts:

def index
  @facts = Fact.all.order("created_at DESC")
end

De tal manera, para iterar usamos el nombre en plural y luego en singular, un ejemplo con Posts sería:

<% @posts.each do |post| %>
  <%= post.title %>
<% end %>

Claro que con las clases de CSS en medio se ve un poco más complejo, pero te aseguro que no lo es.

También usamos el strftime para mostrar la fecha de creación de los Facts de una manera agradable al usuario. Puedes usar For a Good Strftime para mostrar la fecha en el orden que desees.

Finalmente, utilizamos <%= image_tag fact.user.avatar.url(:thumb), class: “ui circular avatar image” %>. image_tag le dice a Rails que deseas insertar una imagen, es la manera adecuada de hacerlo, en lugar de <img src="…">, pasamos la URL del avatar del usuario que lo creo y le decimos que deseamos la miniatura (:thumb), recuerda que lo definimos más atrás, cuando le dimos la capacidad a los usuarios de subir avatars, para ser más precisos, y si deseas añadir otro o modificarlo, en el archivo user.rb es la linea:

has_attached_file :avatar, :styles ...
  • app/views/facts/_form.html.erb:

Deberías de estar familiarizado con lo que estamos haciendo, de nuevo, solo aplicamos clases de Semantic UI y añadimos el campo para subir imagenes.

Hablando de las imagenes, debemos permitir que sean subidas, así que en tu controlador de Facts realiza la siguiente modificación:

def fact_params
  params.require(:fact).permit(:title, :description, :image)
end

Espero notes la adición al final (:image).

  • app/views/facts/new.html.erb:

    <div class="ui container">
      <%= render "form" %>
    </div>
    

Simplemente renderizamos nuestro formulario.

  • app/views/facts/_edit_form.html.erb:

Creamos otro formulario ya que en la edición no permitiremos que el usuario cambie la imagen, solo su titulo y descripción.

  • app/views/facts/edit.html.erb:

    <div class="ui container">
      <%= render "edit_form" %>
    </div>
    

Renderizamos nuestro formulario.

  • app/views/facts/show.html.erb:

Nuevamente sintáxis con la que deberías de estar acostumbrado ya. Date un respiro y felicitarte por haber llegado hasta aquí. No quiero sonar vanidoso, pero la aplicación se ve mucho mejor.

En el próximo capítulo, añadiremos un sistema de roles y autorización.