Guías de Make it Real
  • Introduction
  • Preparación
    • Conceptos básicos
    • El editor de texto
    • La línea de comandos
    • Git y Github
  • Git
    • Instalación y configuración
    • Conceptos y comandos esenciales
    • Ignorando archivos y carpetas
    • Trabajando con ramas
    • Repositorios remotos
    • Etiquetas
    • Reescribiendo la historia
    • Stashing
    • Github
  • HTML y CSS
    • Introducción a HTML
    • Introducción a CSS
    • Más elementos de HTML
    • Tablas
    • Formularios
    • El modelo de caja en CSS
    • Fondos (backgrounds)
    • Posicionamiento
    • Selectores CSS
    • Bordes, sombras y gradientes
    • Media Queries
    • Unidades en CSS
    • Flexbox
  • Bootstrap 3
    • Primeros pasos
    • Elementos básicos de HTML
    • Componentes
    • La grilla
    • Personalizando Bootstrap
    • Utilizando plantillas
  • Bootstrap 4
    • Primeros pasos
    • Elementos básicos de HTML
    • Componentes
    • La grilla
    • Clases utilitarias
    • Personalizando Bootstrap
  • Ruby
    • Primeros pasos
    • Tipos y operadores
    • Variables y entrada de usuario
    • Condicionales
    • Ciclos
    • Arreglos
    • Más cadenas de texto
    • Hashes
    • Métodos
    • Manipulación de archivos
    • Gemas
  • Programación Orientada a Objetos en Ruby
    • Clases y objetos
    • Métodos y atributos de clase
    • Herencia
    • Módulos
    • Excepciones
  • JavaScript I
    • Primeros pasos
    • Tipos y operadores
    • Variables
    • Condicionales
    • Ciclos
    • Arreglos
    • Más cadenas de texto
    • Funciones
    • Objetos literales
    • Manipulación de archivos
  • JavaScript en el navegador
    • Primeros pasos
    • Manipulando HTML
    • Escuchando eventos
    • Local Storage
    • History API
    • Canvas
    • Notificaciones Web
    • Audio y Video
    • Arrastrar y soltar
    • JSON
    • Realizando peticiones HTTP
  • jQuery
    • Primeros pasos
    • Manipulando HTML
    • Escuchando eventos
    • Plugins
    • Realizando peticiones con AJAX
  • JavaScript II
    • Prototipos
    • Librerías (Node.js)
    • ES6
    • Uso de this (call, apply, bind)
    • Programación funcional
    • Scope, hoisting, closures
    • Programación asincrónica
    • Testing
  • HTTP y Sinatra
    • Primeros pasos con Sinatra
    • El protocolo HTTP
    • Rutas
    • Formularios
    • Cookies y sesión
  • Bases de datos
    • Bases de datos relacionales
    • SQL
    • DDL
    • MongoDB
  • Ruby on Rails I
    • Primeros pasos
    • Arquitectura
    • Rutas
    • Layouts y rendering
    • ActiveRecord - Modelos
    • ActiveRecord - Migraciones
    • ActiveRecord - Validaciones
    • ActiveRecord - Asociaciones
    • ActiveRecord - Scopes
    • ActiveRecord - Callbacks
    • Recursos REST
    • Formularios
    • Autenticación con Devise
    • Sass y Bootstrap
    • Envío de correos
    • Carga de imágenes
    • Seeds
    • Heroku
  • Ruby on Rails II
    • Usando JavaScript (y jQuery) en Rails
    • Testing en Ruby
    • Testing en Rails
    • Creando una Web API
    • Web Sockets
  • Express.js
    • Primeros Pasos
    • El protocolo HTTP
    • Rutas
    • Vistas
    • Middlewares y manejo de errores
    • Formularios
    • Cookies y sesión
  • Express.js II
    • Mongoose
    • Web Sockets
    • Autenticación
    • Envío de correos
    • Cargar imágenes
    • Deployment
    • Testing
    • Creando una Web API
  • React
    • Primeros pasos
    • JSX
    • Componentes
    • Más sobre estado
    • Formularios
    • Peticiones HTTP con Axios
    • React Hooks
    • React Context
    • React Bootstrap
    • React Router
    • Carga de Imágenes
    • Testing
    • Estructura de carpetas
    • Componentes de clase
  • Redux
    • Primeros pasos
    • Action creators
    • Usando la librería react-redux
    • Middlewares
    • Operaciones asincrónicas con redux-thunk
    • Combinando funciones reductoras
    • Testing
    • Redux Tool Kit
  • Algoritmos
    • Describiendo un algoritmo
    • Complejidad (Big-O)
    • Estructuras de datos
    • Recursión
    • Ordenamiento
    • Búsqueda
    • Programación dinámica
  • Python
    • Primeros Pasos
    • Tipos y Variables
    • Funciones
    • Control de Flujo
    • Listas
    • Ciclos
    • Diccionarios, Tuplas y Sets
  • NumPy
    • Primeros Pasos
    • Arreglos
    • Arreglos Multidimensionales
    • Estadística con NumPy
    • Distribución Estadística
  • Pandas
    • Primeros Pasos
    • Inspección y Selección de Datos
    • Modificando Dataframes
    • La Función Lambda
    • Aggregates en Pandas
    • Múltiples Tablas
Powered by GitBook
On this page
  • Definiendo las rutas de un recurso
  • Utilizando el generador de recursos
  • El controlador y las vistas de un recurso
  • Listando registros
  • Mostrando los detalles de un registro
  • Mostrando el formulario de creación
  • Creando un registro
  • Mostrando el formulario de edición
  • Actualizando un registro
  • Eliminando un registro
  • Limitando las acciones
  • Notificaciones
  • Mostrando las notificaciones
  • Filtros
  • Limitando el alcance de los filtros
  1. Ruby on Rails I

Recursos REST

REST es una forma particular de definir las rutas HTTP para hacer el CRUD de los modelos en nuestra aplicación Web.

A los modelos también se les conoce como recursos.

Por ejemplo, las rutas para hacer el CRUD de un modelo Product serían las siguientes:

Verbo
Path
Controlador#Acción
Descripción

GET

/products

products#index

muestra la lista de productos

GET

/products/new

products#new

muestra el formulario para crear un producto

POST

/products

products#create

crea un nuevo producto

GET

/products/:id

products#show

muestra los detalles de un producto

GET

/products/:id/edit

products#edit

muestra el formulario para editar un producto

PATCH/PUT

/products/:id

products#update

actualiza un producto

DELETE

/products/:id

products#destroy

eliminar un producto

Definiendo las rutas de un recurso

Para definir las rutas de un recurso en config/routes.rb se utiliza la palabra resources:

resources :products

La línea anterior es equivalente a las siguientes 8 rutas:

get "/products", to: "products#index"
get "/products/new", to: "products#new"
post "/products", to: "products#create"
get "/products/:id", to: "products#show"
get "/products/:id/edit", to: "products#edit"
put "/products/:id", to: "products#update"
patch "/products/:id", to: "products#update"
delete "/products/:id", to: "products#destroy"

Para actualizar un recurso podemos utilizar el verbo PUT o PATCH.

Utilizando el generador de recursos

Así como desde la consola podemos generar un modelo y un controlador, existe un generador que nos permite crear un recurso, que genera el modelo y el controlador.

Por ejemplo, para generar el recurso de productos, es decir, el modelo Product y el controlador ProductsController utilizaríamos el siguiente comando:

$ rails g resources products name  description:text price:decimal

Ese comando genera, entre otros, lo siguiente:

  • El modelo Product en app/models/product.rb

  • La migración que se va a utilizar para crear la tabla.

  • El controlador en app/controllers/products_controller.rb

  • El archivo products.scss en app/assets/stylesheets/.

  • El archivo products.coffee en app/assets/javascripts/.

  • La línea resources :products en config/routes.rb.

No olvides correr la migración:

$ rails db:migrate

El controlador y las vistas de un recurso

El controlador de un recurso está compuesto de las siguientes acciones (métodos):

  • index para mostrar la lista de registros.

  • show para mostrar los detalles de un registro.

  • new para mostrar el formulario de creación.

  • create para crear un registro.

  • edit para mostrar el formulario de edición.

  • update para actualizar un registro.

  • destroy para eliminar un registro.

Veamos cómo se implementaría cada una de estas acciones para un modelo Product.

Listando registros

El método index en el controlador ProductsController quedaría de la siguiente forma:

def index
  @products = Product.all
end

Y la vista en app/views/products/index.html.erb:

<h1>Productos</h1>
<table>
  <thead>
    <tr>
      <th>Nombre</th>
      <th>Descripción</th>
      <th>Precio</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <% @products.each do |product| %>
      <tr>
        <td><%= product.name %></td>
        <td><%= product.description %></td>
        <td><%= product.price %></td>
        <td>
          <%= link_to "Mostrar", product %>
          <%= link_to "Editar", edit_product_path(product) %>
          <%= link_to "Eliminar", product, method: :delete, data: { confirm: "¿Estás seguro de eliminar este producto?" } %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>

Mostrando los detalles de un registro

El método show quedaría de la siguiente forma:

def show
  @product = Product.find(params[:id])
end

Y la vista en app/views/products/show.html.erb quedaría de la siguiente forma:

<h1>Detalles del Producto</h1>
<div>Nombre: <%= @product.name %></div>
<div>Descripción: <%= @product.description %></div>
<div>Precio: <%= @product.price %></div>

Mostrando el formulario de creación

La creación de un registro se divide en dos: la ruta que muestra el formulario y la ruta que inserta el registro en la base de datos cuando alguien llena el formulario.

Para mostrar el formulario se utiliza el método new que se implementaría de la siguiente forma:

def new
  @product = Product.new
end

Y la vista en app/views/products/new.html.erb sería la siguiente:

<%= form_for @product do |f| %>
  <div>
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div>
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>
   <div>
    <%= f.label :price %><br>
    <%= f.number_field :price %>
  </div>

  <div>
    <%= f.submit %>
  </div>
<% end %>

Creando un registro

Para crear el registro necesitamos implementar el método create y un método de ayuda product_params:

def create
  @product = Product.new(product_params)
  if @product.save
    redirect_to products_path
  else
    render :new
  end
end

private
  def product_params
    params.require(:product).permit(:name, :description, :price)
  end

La razón por la que tuvimos que crear ese método de ayuda es por un tema de seguridad. Ese método está filtrando la información que queremos que se pueda cambiar directamente. A esto se le conoce como strong parameters.

No necesitamos una vista para esta acción.

Mostrando el formulario de edición

Para mostrar el formulario de editar se utiliza el método edit que se implementaría de la siguiente forma:

def edit
  @product = Product.find(params[:id])
end

Y la vista en app/views/products/edit.html.erb sería la siguiente:

<%= form_for @product do |f| %>
  <div>
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div>
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>
   <div>
    <%= f.label :price %><br>
    <%= f.number_field :price %>
  </div>

  <div>
    <%= f.submit %>
  </div>
<% end %>

El formulario de edición es igual al de creación, así que una buena práctica es moverlo a un partial _form.html.erb.

Actualizando un registro

Para actualizar el registro necesitamos implementar el método update y el método de ayuda product_params que ya creamos previamente:

def update
  @product = Product.find(params[:id])
  if @product.update(product_params)
    redirect_to products_path
  else
    render :edit
  end
end

No necesitamos una vista para esta acción.

Eliminando un registro

Para eliminar un registro necesitamos implementar el método destroy:

def destroy
  product = Product.find(params[:id])
  product.destroy

  redirect_to products_path
end

Limitando las acciones

Para limitar las rutas y acciones de un recurso utiliza la opción only o except de resources en config/routes.rb:

resources products, only: [:index, :new, :create]
resources articles, except: [:destroy]

En este caso, para products sólo se generarían 3 rutas: la de listar, la de mostrar el formulario y la de crear.

Para resources se generarían todas excepto la de eliminar.

Notificaciones

Para mostrar notificaciones de éxito al crear, editar y eliminar registros utilizando el flash.

Por ejemplo, para mostrar una notificación de éxito al eliminar un producto:

def destroy
  product = Product.find(params[:id])
  product.destroy

  flash[:notice] = "El producto ha sido eliminado exitosamente"
  redirect_to products_path
end

El notice también se puede agregar directamente sobre el redirect_to:

redirect_to products_path, notice: "El producto ha sido eliminado exitosamente"

Mostrando las notificaciones

Puedes agregar el siguiente código donde quieres que aparezcan los mensajes de flash en el layout app/views/layouts/application.html.erb:

<% flash.each do |name, msg| -%>
  <%= content_tag :div, msg, class: name %>
<% end -%>

Filtros

Puedes ejecutar métodos que se ejecutan antes o después de una acción de un controlador utilizando before_action y after_action.

Por ejemplo, podemos verificar si los usuarios ya están autenticados con un before_action:

class ApplicationController < ActionController::Base
  before_action :require_login

  private
    def require_login
      unless logged_in?
        flash[:error] = "You must be logged in to access this section"
        redirect_to new_login_url # halts request cycle
      end
    end
  end

Si haces un render o redirect_to en un before_action la acción no se ejecuta.

Los filtros son heredados, así que si defines el filtro en ApplicationController se va a ejecutar en todos los controladores de la aplicación.

Limitando el alcance de los filtros

Puedes limitar las acciones a las que aplica un filtro utilizando las opciones only o except.

Por ejemplo:

before_action :require_login, only: [:new, :create]
before_action :require_login, except: [:index]
PreviousActiveRecord - CallbacksNextFormularios

Last updated 2 years ago