DEV Community

Daniel-Penaloza
Daniel-Penaloza

Posted on

ViewComponent On Rails

Introducción.

Si hay algo que siempre me ha gustado de ruby/rails es su comunidad, siento que es una comunidad súper rica en nuevas propuestas, que sigue con buenas convenciones y que ademas siempre trata de tener el código ordenado. De tal manera que al momento de crear algo nos evitemos tantos comentarios en el código y este hable por si mismo.

Que es ViewComponent?.

ViewComponent viene a ser un entorno de trabajo para la creación de componentes encapsulados de vistas que pueden ser reutilizables y testeables con mayor facilidad.
En este breve tutorial nos vamos a enfocar en crear ViewComponents básicos.

La problemática (Barra de progreso)!

Supongamos que tenemos la necesidad de crear una barra de progreso para varias vistas en una aplicación.
Por ejemplo en una todo list o en un finance tracker o algo parecido, el caso es que queremos que por lo menos este mas de una vez repetido este componente sobre nuestra aplicación.
Primero que nada imagínense la repetición de código HTML que vamos a tener que incorporar en nuestra aplicación, sinceramente esto no es practico y para nada estaríamos respetando el DRY.

<div class="progress">
  <div class="progress-bar" role="progressbar" style="width: <%= @valor_de_tu_objeto %>" aria-valuenow="<%= @valor_de_tu_objeto %>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

Lo cual nos desplegara lo siguiente en cada una de las vistas que deseemos.
Image description
Para venir a salvarnos de este tipo de cosas y tener mejor organizado nuestro código aquí es en donde se presentan los ViewComponents.
Yes

Hands On

Para poder hacer uso de los ViewComponents es necesario instalar la siguiente gema.

gem "view_component", require: "view_component/engine"

# Posteriormente ejecutar bundle install
Enter fullscreen mode Exit fullscreen mode

Una vez instalada la gema procederemos a crear el componente con el siguiente comando.

bin/rails g component ProgressBarComponent value
Enter fullscreen mode Exit fullscreen mode

Este comando nos creara mas o menos la siguiente salida en terminal

invoke test_unit
create test/components/progress_bar_component_test.rb
create app/components/progress_bar_component.rb
create app/components/progress_bar_component.html.erb
Enter fullscreen mode Exit fullscreen mode

Por lo tanto con esto podemos deducir que un ViewComponent esta compuesto por un archivo (progress_bar_component.rb) y una plantilla (progress_bar_component.html.erb).
Dado que cuando ejecutamos el generador de componentes pasamos un atributo (value) entonces nuestro component lucirá de la siguiente manera.

# app/components/progress_bar_component.rb

# frozen_string_literal: true

class ProgressBarComponent < ViewComponent::Base
    def initialize(value:)
      @value = value
    end
end
Enter fullscreen mode Exit fullscreen mode

Ahora sera momento de agregar nuestro código HTML para la barra de progreso de la siguiente manera.

# app/components/progress_bar_component.html.erb
<div class="progress mb-4">
  <div class="progress-bar bg-info" role="progressbar" style="width: <%= @value %>%;" aria-valuenow="<%= @value %>" aria-valuemin="0" aria-valuemax="100" ></div>
</div>
Enter fullscreen mode Exit fullscreen mode

Llamada desde una vista diferente

Supongamos que deseamos ahora llamar a este componente desde una vista index en donde tengamos una todo list con una cantidad de porcentaje completado de un modelo, para poder hacerlo deberíamos de hacerlo de la siguiente manera.

  • Calculamos el porcentaje completado de todos.
# app/models/todo.rb
def percent_complete
  Todo.count == 0 ? 0 : (100 * completed_items.to_f / total_items).round(1)
end
# El método anterior se puede descomponer para hacerlo mas legible ya lo dejo a su criterio.
Enter fullscreen mode Exit fullscreen mode
  • Mandamos a llamar desde la vista que deseemos implementar la barra de progreso.
# app/views/todos/index.html.erb
<%= render(ProgressBarComponent.new(value: @todo.percent_complete)) %>
Enter fullscreen mode Exit fullscreen mode

De esta manera este componente es totalmente re-utilizable en cualquier otra vista de nuestra aplicación sin necesidad de escribir nuevamente el código HTML y solo mandando a llamar al componente por medio del método render.

Fuentes y Recomendaciones.

  • View Components
  • Revisen con detenimiento las colecciones con ViewComponents son una chulada para reducir código.
  • He estado probando los ViewComponents con alguna que otra cosilla de Stimulus Reflex (en algún momento hablare acerca de este tema) y les puedo comentar que trabajan muy bien en conjunto.

Oldest comments (0)