Frameworks MVC y Ruby on Rails

Juan Manrique
Academia Hack
Published in
11 min readJul 4, 2019

En pocos años la Web evolucionó enormemente: ha pasado de páginas sencillas, con pocas imágenes y contenidos estáticos a páginas complejas con contenidos dinámicos que provienen de bases de datos, lo que permite la creación de “aplicaciones web”.

De forma breve, una aplicación web se puede definir como una aplicación en la que un usuario, por medio de un navegador web, realiza peticiones a una aplicación remota accesible a través de Internet (o a través de una intranet) y que recibe una respuesta que se muestra en el propio navegador.

Problemas presentes al desarrollar aplicaciones web

  • Aumento de la complejidad del código para el desarrollo de grandes aplicaciones.
  • Aplicaciones no reutilizables.
  • Acceso a los datos y lógica del negocio entrelazados con la interfaz.
  • Incremento del esfuerzo requerido para la implementación, prueba y mantenimiento de la aplicación.
  • No hay separación de los roles de programador y diseñador gráfico de vistas durante el desarrollo de la aplicación.
  • Múltiples aplicaciones deben ser desarrolladas para distintos usuarios basados en la misma lógica del negocio.
  • Duplicación de código.

Patrones de diseño de arquitectura

Los patrones de diseño son el esqueleto de las soluciones a problemas comunes en el desarrollo de software. Estos brindan soluciones ya probadas y documentadas a problemas de desarrollo de software que están sujetos a contextos similares. Ej. Active Record es un patrón de diseño porque gestiona mecanismos de persistencia de datos.

Los patrones de arquitectura son patrones de diseño de software que ofrecen soluciones a problemas de arquitectura de software. Dan una descripción de los elementos y el tipo de relación que tienen junto con un conjunto de restricciones sobre cómo pueden ser usados. Un patrón arquitectónico expresa un esquema de organización estructural esencial para un sistema de software, que consta de subsistemas, sus responsabilidades e interrelaciones

En el caso de aplicaciones Web se implementa el patrón de arquitectura MVC

MVC (Modelo-Vista-Controlador)

Es un patrón de arquitectura de software que separa los datos de una aplicación, la interfaz de usuario, y la lógica de negocio en tres componentes distintos. Pretende separar el modelo de datos de la vista para poder realizar cambios en la vista y que estos no afecten al modelo de datos.

Modelo

  • Representa los datos y operaciones sobre ellos
  • Accede a la capa de almacenamiento de datos
  • Define las reglas de negocio
  • Lleva un registro de las vistas y controladores del sistema
  • Si estamos ante un modelo activo, notificará a las vistas los cambios que en los datos pueda producir un agente externo

Vista

  • Es la representación visual del modelo
  • Recibe datos del modelo y los muestra al usuario
  • Tiene un registro de su controlador asociado
  • Cuando es un modelo activo que informa de los cambios en los datos producidos por otros agentes, da el servicio de actualización, para que sea invocado por el controlador o por el modelo

Controlador

  • Se encarga de ser intermediario entre el modelo y la vista, y coordinar la ejecución
  • Recibe los eventos de entrada (un clic, un cambio en un campo de texto, etc.)
  • Contiene reglas de gestión de eventos, estas acciones pueden suponer peticiones al modelo o a las vistas

Analogías

  • En tu televisor puedes ver distintos canales distribuidos por tu proveedor de cable (que representa al modelo), todos los canales que puedes ver son la vista, y tú cambiando de canal, controlando qué ves, representas el controlador.

Ejercicio rápido: Estás en una cafetería y pides un café con leche al mesero, el mesero la prepara y te la entrega (identifique cual es la vista, cual es el controlador y cual es el modelo).

Respuesta: El cerebro del mesero es el controlador, el recibe la petición del usuario (una café) y va hacia la cocina a prepararlo. El modelo son los ingredientes para preparar el café porque son los recursos que tienes, finalmente el café (la vista) está listo y es entregado al cliente

Ejemplo aplicado a la web

Este checkbox posee:

Un modelo: que se encarga de almacenar los datos del checkbox, en este caso, un solo dato que puede ser verdadero (checked) o falso (not checked).

Una vista: la representación gráfica del checkbox, es decir una cajita. La vista por supuesto toma los datos del modelo para saber cómo debe ser representada (con o sin marca). El usuario por supuesto ve e interactúa con la aplicación a través de la vista.

Un controlador: El controlador se encarga de tomar una acción del usuario (por ejemplo el usuario presionó el checkbox) y actualizar el modelo (en este caso ahora el modelo contendrá “verdadero” porque el checkbox está presionado o volverá a “falso” si se presiona otra vez).

Una vez que se realicen cambios en el modelo, éste actualiza la vista

Ventajas

  • Flexibilidad para cambiar las vistas y los controladores
  • Se pueden añadir y actualizar controladores y vistas conforme cambia el modelo
  • Múltiples vistas del mismo modelo
  • Vistas sincronizadas
  • La aplicación puede soportar distintos tipo de interfaz de usuario
  • Es muy usado en el desarrollo de aplicaciones Web, sobre todo por los frameworks

Desventajas

  • Complejidad creciente: se crean muchos archivos, la lógica puede ser compleja inicialmente
  • Cambios innecesarios
  • Conexión entre la vista y el controlador
  • Acceso ineficiente a los datos en la vista

La web es complicada, necesitas saber HTML, CSS, javascript, un lenguaje de backend y probablemente SQL. Muchas aplicaciones necesitan formularios de autenticación, resetear contraseñas, API’S, enviar correos, proceso de pagos, deployment, etc. Es entonces cuando necesitamos de los frameworks.

Framework

Un framework es una estructura software compuesta de componentes personalizables e intercambiables para el desarrollo de una aplicación. Es un marco (Framework) en el que nosotros vamos a definir piezas. El marco define las reglas del juego a las que nos tenemos que atener. Pensemos en ellos como un puente para realizar código más rápido y fácil.

Los objetivos principales que persigue un framework para la web son: acelerar el proceso de desarrollo, reutilizar código ya existente y promover mejores prácticas de desarrollo como el uso de patrones de diseño.

Haciendo una analogía, podemos imaginar que el framework es un conjunto de ingredientes culinarios cortados y preparados para usarlos. Según qué componentes utilizamos y cómo los hayamos cocinado, crearemos un plato u otro.

Ejemplos de frameworks

  • CodeIgniter (php)
  • CakePHP
  • Symfony
  • Ruby on Rails
  • Padrino
  • ASP.NET

Analogía

Los frameworks son como un taller donde construyen carros(web app) y ya tienen componentes construidos reutilizables para distintos carros. Sin embargo pueden existir que se necesitan partes específicas para un modelo de un carro que no existe o que no hacen match entonces el taller es capaz de crear nuevas partes que satisfagan esos nuevos requerimientos

Ruby on Rails

Es un framework para crear aplicaciones web escrito en Ruby. Ruby on Rails (RoR) implementa el patrón de arquitectura MVC (Modelo Vista Controlador). Usa ActiveRecord, que es un ORM que permite hacer consultas a la base de datos a través de objetos y REST (Representational State Transfer) que es un paradigma para definir rutas en aplicaciones web. En base a REST, las aplicaciones de Ruby on Rails determinan qué parte de aplicación mostrar y cómo responder a las solicitudes del usuario.

Rails es dogmático

Esto se refiere que a diferencia de Perl, por ejemplo, que es un lenguaje de programación en donde hay más de una forma de hacer cada cosa y no hay la manera correcta ni la mejor forma. Hay un “Rails way” para muchos de los problemas que debe resolver una aplicación web si sigues estas convenciones de rails entonces tendrás menos decisiones que tomar y te darás cuenta que muchas de las cosas que necesitas ya están hechas. El beneficio de esto es que puedes desarrollar más rápido, mejorar la colaboración y es más fácil de mantener.

Convention Over Configuration

Algunos frameworks, como los de Java para aplicaciones web necesitan hacer una múltiple cantidad de configuraciones en archivos y cada una con muchos ajustes. Rails esto te lo hace mucho más fácil asumiendo cosas, así por ejemplo si tu creas por convención un modelo en Rails llamado “User”, te creará una tabla en tu base de datos llamada “Users” sin ninguna configuración requerida y además Rails asumirá que si el nombre de la tabla es plural si el nombre de la clase es singular.

Don’t Repeat Yourself

Conocido por el acrónimo DRYS, es un principio de desarrollo de software. Tal como su nombre lo dice trata en evitar los duplicados, ya que los duplicados hacen el código más complejo, difícil de mantener y más vulnerable a errores.

Rails toma ventaja de las características de metaprogramming de ruby que tienen no sólo para reusar código sino que además para eliminar código donde sea posible.

Fun fact: ¿Por qué el nombre Ruby on Rails?

DDH: When I first came up with Rails, it was inspired by an old Java framework called Struts. I liked how it was short and had a builder’s taste to it. But when I went to register rails.org, it was taken, but RubyOnRails.org wasn’t. I ended up liking the longer name even better as it highlighted the true magic of Rails: How it uses Ruby.

Cuando se me ocurrió Rails por primera vez, me inspiré en un antiguo framework de Java llamado Struts. Me gustó que era corto y sonaba a constructor. Pero al intentar registrar rails.org, ya estaba registrado, pero RubyOnRails.org no lo estaba. Al final, me gustó el nombre largo, incluso más que el anterior ya que destacaba la magia real de Rails: cómo utiliza Ruby.

Estructura de las carpetas en rails

app : esta carpeta contiene tu aplicación. Por lo tanto, es la carpeta más importante en Ruby on Rails y vale la pena profundizar en sus subcarpetas:

  • app/assets: Los assets son básicamente cosas de front-end. Esta carpeta contiene imágenes y hojas de estilo usadas en las vistas del website.
  • app/channels: Un framework que permite la utilización de WebSockets en nuestra aplicación
  • app/controllers: contiene los controladores que manejan las peticiones de los usuarios. A menudo, responden por un solo tipo de recurso, como lugares o usuarios. Los controladores también enlazan los modelos con las vistas.
  • app/helpers: los helpers se utilizan para implementar la lógica que se necesita en las vistas y, así, mantenerlas libres de reglas de negocio y poder reutilizar esta lógica en múltiples vistas.
  • app/javascript: dentro de esta carpeta se encontrará todo el código JavaScript de nuestra aplicación.
  • app/job: mediante ActiveJob podemos generar colas de tareas que se ejecutarán cuando lo determinemos y según lo que necesite nuestra aplicación
  • app/mailers: Esta carpeta contiene la lógica necesaria para generar y gestionar el envío de correos electrónicos.
  • app/models: contiene las implementaciones de los modelos que definen las reglas de negocio de nuestra aplicación. Por ejemplo, los modelos Person o Location, con todo su comportamiento típico.
  • app/views: esta carpeta contiene los templates de las vistas que se mostrarán al usuario después de un request exitoso. Por defecto, están escritos en HTML con Ruby embebido (.html.erb). El Ruby embebido se utiliza para inyectar datos a las vistas. Luego, se convierten en HTML y se envían al cliente. Tiene subcarpetas para cada recurso de la aplicación. Estas subcarpetas contienen los archivos de vistas asociadas a cada recurso. Los archivos que comienzan con un guión bajo (_) se denominan partials. Esas son partes de una vista que se reutilizan en otras vistas. Un ejemplo común es _form.html.erb que contiene el formulario básico para un recurso dado. Se usa en la vista new y en la vista edit, ya que crear y editar un recurso se hace de forma similar.

bin: WIP

config: esta carpeta contiene los archivos de configuración de la aplicación, como los de base de datos (database.yml) y las rutas (routes.rb) que deciden cómo se manejan las peticiones HTTP. El archivo routes.rb hace coincidir una URL determinada con el controlador que manejará la solicitud.

db: contiene una gran cantidad de archivos relacionados con la base de datos. Lo más importante es la carpeta migrations, que contiene todos los archivos de migrations de la base de datos. Los migrations defiinen la estructura de la base de datos (atributos de modelos). Mediante migrations se agregan nuevos atributos a los modelos existentes o se crean nuevos modelos.

lib: abreviatura de library. Contiene librerías personalizadas, assets y script que necesitemos para nuestra apliacación

log: toda la salida escrita en consola desde que se inició el servidor Rails, está escrito en el log de desarrollo. Los logs contienen información de la ejecución de la aplicación. Si ocurre un error, será registrado en los logs.

public: contiene vistas estáticas que no contienen código Ruby, como páginas de error, 404, etc.

storage: por defecto, es el lugar donde se almacenan los archivos del gestionados con ActiveStorage

test: contiene los tests de la aplicación. Con los tests se asegura de que la aplicación realmente haga lo que se espera.

vendor: una carpeta para el código escrito por otros (“libraries”). La mayoría de las veces, las librerías se proporcionan como gems de Ruby y se instalan con el archivo Gemfile. Si el código no está disponible como un gem de Ruby, debe ponerse aquí.

Gemfile: es un archivo en el que se especifica la lista de gems (dependencias) necesarios para que corra la aplicación. Rails en sí es un gem que encontrarás en el Gemfile. Los gems de Ruby son paquetes de código independientes, generalmente llamados librerías, que agregan funcionalidad o características a la aplicación. Si se desea agregar un nuevo gem a la aplicación, agrega “gem nombre_del_gem” al Gemfile, especificando opcionalmente un número de versión. Guarda el archivo y luego ejecuta bundle install para instalar el gem.

Gemfile.lock: este archivo especifica las versiones exactas de todas los gems. Debido a que algunos gems dependen de otros gems, Ruby instalará todo lo necesario automáticamente. El archivo también contiene números de versiones específicos. Se puede usar para asegurarse de que todos los miembros del equipo trabajen con las mismas versiones de gems. El archivo se genera automáticamente. No se debe editar este archivo manualmente.

Comandos generadores del terminal de Rails

  • Crear un nuevo proyecto
rails new [--api] nombre_app

Este comando permite crear un nuevo proyecto llamado app_name. Se creará una carpeta con este mismo nombre y, dentro de ella, toda la estructura de carpetas de Rails.

  • Correr el servidor
rails server
o
rails s

El servidor de aplicaciones de desarrollo debe ejecutarse para que una aplicación pueda recibir solicitudes. Este comando puede tardar un poco. Una vez arriba el rails server, se podrá acceder a la aplicación desde el navegador en la dirección `localhost:3000`. Para detener el servidor, se combinan las teclas `ctrl + c` en el terminal.

  • Crear un model
rails g model Modelo attribute:type
  • Crear un controller
rails g controller NombreEnPlural action
  • Correr los seeds
rails db:seed
  • Correr los migrations
rails db:migrate

Se debe ejecutar este comando cada vez que se agreue un nuevo migration a fin de actualizar la base de datos.

  • Inspeccionar las rutas
rails routes
  • Instalar dependencias
bundle install

Se debe ejecutar este comando cada vez que se agregue un gem al Gemfile para instalarlo.

  • Consola de Rails
rails creload!

Algunos websites desarrollados en Ruby on Rails

--

--

Juan Manrique
Academia Hack

SW developer. Coding Mentor @academia_hack. Agile promoter. Writer. Simplifier. Motivator. Venezuelan Rums Expert Evangelist. At your services.