¿Por qué son tan importantes las buenas prácticas en Ruby on Rails o en cualquier proyecto? Las razones son muchas pero 3 de las más importantes son:

  • Mantenimiento del código: Un código bien estructurado y organizado es más fácil de mantener y de modificar. Esto es especialmente importante en proyectos a largo plazo.
  • Colaboración en equipo: En proyectos con varios desarrolladores, seguir buenas prácticas ayuda a que todos los miembros del equipo puedan entender y trabajar en el código de los demás. Y si tu equipo aún es pequeño, seguir buenas prácticas te ayudará a que cuando crezca, la transición sea más sencilla.
  • Calidad del código: Las buenas prácticas ayudan a prevenir errores y vulnerabilidades de seguridad, lo que se traduce en un código más robusto y confiable. Además, facilitan la detección y corrección de errores.

Rails es mágico, pero no adivino

Ruby on Rails es un framework que fomenta muchas buenas prácticas por defecto. Una clara muestra de ello es:

  • Rails sigue el patrón de diseño Modelo-Vista-Controlador (MVC) y tiene una estructura de archivos y carpetas predefinida que facilita la separación de preocupaciones. Esto es un gran punto a favor del principio de responsabilidad única.
  • Rails sigue el principio convención sobre la configuración, lo que significa que sigue ciertas convenciones y buenas prácticas por defecto. Por ejemplo, Rails espera que los nombres de las tablas de la base de datos estén en plural y en minúsculas, y que los nombres de las clases de los modelos estén en singular y en mayúsculas.

Sin embargo, mientras más crezca tu proyecto, más probable es que necesites personalizar y extender la funcionalidad de Rails, o que necesites integrar otras gemas o servicios. En estos casos, es importante conocer y seguir buenas prácticas para mantener la calidad y la coherencia del código.

Buenas Prácticas con las que puedes empezar

Arquitectura Avanzada

Una de las áreas en las que puedes profundizar es en la arquitectura avanzada de Rails. Algunos temas que puedes explorar son:

  • Patrones de diseño avanzados: Rails ofrece muchas posibilidades para implementar patrones de diseño avanzados, como Service Objects, Decorators, etc. Estos patrones te ayudarán a mantener un código más limpio y modular.
  • Gemas especializadas: Existen muchas gemas especializadas que pueden mejorar la arquitectura de tu aplicación, como Trailblazer, ViewComponent, Cells, etc. Estas gemas te permiten implementar funcionalidades avanzadas y mantener una arquitectura más escalable y mantenible.

Patrones de diseño avanzados

Los patrones de diseño son soluciones generales a problemas comunes en el diseño de software. Algunos patrones de diseño avanzados que puedes aplicar en Rails son:

  • Decorators: Los Decorators son objetos que envuelven a otros objetos y añaden funcionalidades adicionales. Son útiles para añadir presentación y lógica de vista a tus modelos sin sobrecargarlos. Ejemplo de Decorator en Rails:
    class ProductDecorator < SimpleDelegator
    def formatted_price
      number_to_currency(price)
    end
    end
    
  • Policy Objects: Los Policy Objects son objetos que encapsulan la lógica de autorización de tu aplicación. Son útiles para centralizar la lógica de autorización y mantener un código más limpio y reutilizable. Ejemplo de Policy Object en Rails:
    class OrderPolicy
    def initialize(user, order)
      @user = user
      @order = order
    end
    
    def can_create?
      @user.admin? || @user == @order.user
    end
    end
    
  • Presenters: Los Presenters son objetos que encapsulan la lógica de presentación de tu aplicación. Son útiles para separar la lógica de presentación de los modelos y controladores, y para mantener un código más limpio y reutilizable. Ejemplo de Presenter en Rails:
    class ProductPresenter
    def initialize(product)
      @product = product
    end
    
    def formatted_price
      number_to_currency(@product.price)
    end
    end
    
  • Service Objects: Los Service Objects son objetos que encapsulan la lógica de negocio de tu aplicación. Son útiles para separar la lógica de negocio de los controladores y modelos, y para mantener un código más limpio y modular. Ejemplo de Service Object en Rails:
    class CreateOrderService
    def initialize(user, product)
      @user = user
      @product = product
    end
    
    def call
      order = @user.orders.create(product: @product)
      SendOrderConfirmationEmailJob.perform_later(order)
      order
    end
    end
    
  • Query Objects: Los Query Objects son objetos que encapsulan consultas complejas a la base de datos. Son útiles para mantener un código más limpio y reutilizable, y para separar la lógica de consulta de los modelos y controladores. Ejemplo de Query Object en Rails:
    class ProductsQuery
    def initialize(relation = Product.all)
      @relation = relation
    end
    
    def cheap_products
      @relation.where('price < ?', 100)
    end
    end
    

Gemas especializadas

Además de los patrones de diseño avanzados, existen muchas gemas especializadas que puedes utilizar en Rails para mejorar la arquitectura de tu aplicación. Algunas gemas especializadas que puedes explorar son:

  • Trailblazer: Trailblazer es un framework que te ayuda a implementar patrones de diseño avanzados en Rails, como Services (Operation), Presenter, etc. Trailblazer te permite mantener una arquitectura más limpia y modular. Ejemplo de Operation en Trailblazer:
    class CreateOrder < Trailblazer::Operation
    step :validate
    step :create_order
    
    def validate(ctx, params:, **)
      ctx[:order] = Order.new(params)
      ctx[:order].valid?
    end
    
    def create_order(ctx, order:, **)
      order.save
    end
    end
    
  • ViewComponent: ViewComponent es una gema que te ayuda a implementar componentes reutilizables en Rails. Los componentes de ViewComponent te permiten separar la lógica de presentación de los modelos y controladores, y a mantener un código más limpio y modular. Está inspirado en el concepto de componentes de React. Ejemplo de componente en ViewComponent:
    class MessageComponent < ViewComponent::Base
    erb_template <<-ERB
      <h1>Hello, <%= @name %>!</h1>
    ERB
    
    def initialize(name:)
      @name = name
    end
    end
    
  • Cells: Cells es una gema que te ayuda a implementar celdas reutilizables en Rails. Las celdas de Cells te permiten encapsular la lógica de presentación en componentes reutilizables, y a mantener un código más limpio y modular. Ejemplo de celda en Cells:
    class ProductCell < Cell::ViewModel
    def show
      model.name + ' ' + model.price
    end
    end
    
    <% @products.each do |product| %>
    <%= cell(ProductCell, product) %>
    <% end %>
    
  • AASM: AASM es una gema que te ayuda a implementar máquinas de estado en Rails. Esto te permiten modelar el comportamiento de tus modelos de forma más clara y modular, y a mantener un código más limpio y mantenible. Ejemplo de máquina de estado en AASM:
    class Order < ApplicationRecord
    include AASM
    
    aasm do
      state :pending, initial: true
      state :confirmed, before_enter: :send_confirmation_email
      state :shipped
      state :delivered
    
      after_all_transitions :log_status_change
    
      event :confirm do
        transitions from: :pending, to: :confirmed
      end
    
      event :ship do
        after do
          send_shipping_notification
        end
        transitions from: :confirmed, to: :shipped
      end
    
      event :deliver do
        transitions from: :shipped, to: :delivered
      end
    end
    end
    

Adicionalmente, la comunidad de Rails es muy activa y hay muchas gemas que pueden ayudarte a mejorar o avanzar rápidamente en tu proyecto. Una buena práctica es investigar y evaluar las gemas antes de integrarlas en tu proyecto, para asegurarte de que cumplen con tus necesidades y estándares de calidad. Y también recordar que muchas de las funcionalidades comunes entre proyectos ya tienen gemas que las implementan, y estas se dedican a mejorar y mantener esas funcionalidades, sobretodo en términos de seguridad.

Rendimiento y Escalabilidad

Otro aspecto importante en el desarrollo de aplicaciones web es el rendimiento y la escalabilidad. Algunos temas que puedes explorar en este ámbito son:

  • Optimización de rendimiento: Rails ofrece muchas posibilidades para optimizar el rendimiento de tu aplicación, como el uso eficiente de caché, la fragmentación de vistas, etc. Estas estrategias te ayudarán a mejorar la velocidad de carga de tu aplicación y la experiencia del usuario.
  • Arquitecturas escalables: Si tu aplicación crece, es importante tener en cuenta la escalabilidad. Algunas estrategias para implementar arquitecturas escalables en Rails son el uso de microservicios, el sharding de la base de datos, etc.

Optimización de rendimiento

La optimización de rendimiento es un aspecto crítico en el desarrollo de aplicaciones web, ya que influye directamente en la experiencia del usuario y en la eficiencia de la aplicación. Algunas estrategias para optimizar el rendimiento de tu aplicación en Rails son:

  • Uso eficiente de caché: Rails ofrece muchas posibilidades para implementar caché en tu aplicación, como el uso de fragmentos de caché, el uso de caché de página completa, etc. Estas estrategias te ayudarán a mejorar la velocidad de carga de tu aplicación y a reducir la carga en el servidor.
  • Optimización de activos estáticos: Los activos estáticos, como JavaScript, CSS e imágenes, pueden afectar el rendimiento de tu aplicación si no se optimizan correctamente. Algunas estrategias para optimizar los activos estáticos en Rails son la minificación, la concatenación, la compresión, etc.
  • Uso de bases de datos eficientes: La base de datos es uno de los componentes críticos en el rendimiento de una aplicación web. Algunas estrategias para optimizar el rendimiento de la base de datos en Rails son el uso de índices, la optimización de consultas, la fragmentación de tablas, etc.

Seguridad en Profundidad

La seguridad es un aspecto crítico en el desarrollo de aplicaciones web, ya que cualquier vulnerabilidad puede comprometer la integridad y la confidencialidad de los datos de los usuarios. Algunos temas que puedes explorar en este ámbito son:

  • Análisis detallado de vulnerabilidades comunes: Es importante conocer las vulnerabilidades comunes en aplicaciones web, como Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), SQL Injection, etc.
  • Herramientas avanzadas de seguridad: Existen muchas herramientas avanzadas de seguridad que puedes utilizar en Rails, como Brakeman, Bundler Audit, etc. Estas herramientas te ayudarán a identificar y corregir vulnerabilidades de seguridad en tu aplicación. Si tienes tu aplicación en GitHub, tienes a dependabot que te ayuda a mantener tus dependencias actualizadas y seguras.

Análisis detallado de vulnerabilidades comunes

Es importante conocer las vulnerabilidades comunes en aplicaciones web para poder prevenirlas y mitigarlas. Algunas vulnerabilidades comunes en aplicaciones web son:

  • Cross-Site Scripting (XSS): El XSS es una vulnerabilidad que permite a un atacante ejecutar código malicioso en el navegador de un usuario. Para prevenir el XSS en Rails, es importante escapar y sanitizar las entradas del usuario y utilizar métodos seguros para renderizar HTML. Ejemplos de prevención de XSS en Rails:
    • Siempre sanitizar las entradas del usuario antes de mostrarlas en la vista. Esto se puede hacer con el método sanitize o html_safe.
      <%= sanitize @user.bio %>
      
    • Utilizar el link_to solo para enlaces internos y no para enlaces externos.
      <%= link_to 'Home', root_path %>
      
  • Cross-Site Request Forgery (CSRF): El CSRF es una vulnerabilidad que permite a un atacante realizar acciones no autorizadas en nombre de un usuario autenticado. Para prevenir el CSRF en Rails, es importante utilizar tokens de autenticidad y verificar la autenticidad de las solicitudes. Rails proporciona protección contra CSRF por defecto, pero también permite deshabilitarla si es necesario. Para verificar la autenticidad de las solicitudes en Rails, en el ApplicationController o el controlador base de tu aplicación, debe estar la siguiente línea:
    protect_from_forgery with: :exception
    

    Esto significa que Rails usa la estrategio :exception para protegerse de CSRF, que lanza un error si el request viene sin el token de autenticidad. Otra estrategia es :null_session que no lanza un error, pero limpia la sesión. En muchas API hechas en Rails, se usaba el skip_before_action :verify_authenticity_token para deshabilitar la protección CSRF en los controllers que eran solo de la API.

  • SQL Injection: El SQL Injection es una vulnerabilidad que permite a un atacante ejecutar consultas SQL maliciosas en la base de datos. Para prevenir el SQL Injection en Rails, es importante utilizar consultas parametrizadas y escapar las entradas del usuario. Aquí es importante usar los métodos de ActiveRecord que permiten hacer consultas seguras.

Testing

Las pruebas automatizadas son una parte fundamental del desarrollo de software, ya que te permiten verificar el comportamiento de tu aplicación y prevenir errores. Algunos temas que puedes explorar en este ámbito son:

  • Pruebas unitarias: Las pruebas unitarias te permiten verificar el comportamiento de unidades individuales de código, como modelos, controladores, etc.
  • Pruebas de integración: Las pruebas de integración te permiten verificar el comportamiento de múltiples componentes de tu aplicación trabajando juntos.
  • Pruebas de aceptación: Las pruebas de aceptación te permiten verificar el comportamiento de tu aplicación desde la perspectiva del usuario.

Conclusión

En resumen, seguir buenas prácticas en Ruby on Rails es fundamental en muchos aspectos. Algunas áreas en las que puedes profundizar son la arquitectura avanzada, el rendimiento, la escalabilidad, la seguridad y las pruebas automatizadas. Recuerda que la comunidad de Rails es muy activa y hay muchos recursos disponibles para seguir aprendiendo y mejorando en el desarrollo con Rails. ¡Sigue aprendiendo y mejorando en tu viaje con Ruby on Rails!

¡Gracias por leerme! ❤️





You may also enjoy

Optimizing Active Record queries

Context: Some time ago, I worked on a project where I had to make a lot of reports. We had a lot of data, and most of the reports should be in the applicatio...

Authentication with Auth0 on Rails

One of the essential features that most applications have in common is Authentication. There are many options to authenticate us nowadays. In this article, I...

Optimización de queries en Rails

Contexto: Hace un tiempo, trabajé en un proyecto en el que tenía que dar reportes de la data que teníamos, la mayoría de los reportes que teníamos que calcul...

Autenticación con Auth0 en Rails

Uno de los features más importantes que la mayoría de aplicaciones tienen en común es la Autenticación. Hay muchas opciones de autenticarnos actualmente, le...