Modelos sin ActiveRecord en Rails 4

ActiveRecord incluye un potente conjunto de validadores y otras características para los atributos de un modelo de datos persistente. Por otro lado, los formularios son uno de los bloques de construcción más antiguos e importantes de las aplicaciones web de hoy en día, una interfaz esencial para la entrada del usuario. De los dos ayudantes de formulario que proporciona Rails, "form_for" también asume que estás trabajando con algún tipo de objeto persistente. Por lo tanto, puede aprovechar al máximo todas las funciones de registro activo, es decir, las validaciones..

Todo esto es ideal para objetos persistentes con representaciones respaldadas por bases de datos. Pero, ¿qué sucede cuando necesita una forma compleja que no refleja un registro persistente de algún tipo??

En este tutorial hablaré sobre las posibles soluciones para este problema y cómo implementar una en Rails 4 (modelos activos).

En este tutorial, construiremos una aplicación con un formulario donde un usuario puede agregar algunos comentarios que luego se guardan en una base de datos. Esta aplicación también tendrá validaciones y vistas, exactamente de la manera en que las creas para un modelo respaldado por una base de datos, pero luego veremos algunos de los cambios en el modelo para que no tenga tablas. Y todas las características deben estar funcionando como están, sin realizar ningún cambio adicional. No hay acciones de actualización, eliminación o búsqueda para comentarios.

Lo primero es lo primero

Para este tutorial, asumo que tiene una subestimación básica del marco de Rails y puede crear o generar fácilmente controladores, modelos y vistas básicos. Supongo que también sabes un poco sobre cómo funcionan las rutas y las validaciones. En el momento de escribir este tutorial, estaba usando Rieles 4.2.5 y SQLite 3.8.10.2.

Introducción

Puede haber muchas situaciones cuando tiene una clase en la que desea funcionar como un modelo típico de ActiveRecord, pero no desea conservar los datos en la base de datos. Por ejemplo, puede tener un formulario de contacto o algo más complejo, como un formulario de queja o de comentarios. 

En esas situaciones, para resolver este problema, un enfoque sería utilizar el form_tag Método auxiliar, que le proporciona campos de formulario personalizados que hacen lo que necesita sin tener que vincularlos con ningún modelo..

Esto funciona bien, pero form_tag puede volverse tedioso escribir y mantener rápidamente si maneja más de unos pocos campos debido a la necesidad de manejar nombrando sus numerosos atributos y sus validaciones por su cuenta. Pronto su controlador terminará manejando mucha lógica y toneladas de formularios de formas, lo que probablemente no sea la solución ideal.

Un enfoque más limpio y flexible sería si pudiéramos utilizar el mismo form_for con un modelo y todas las validaciones y otras ventajas con las que vienen, pero sin necesidad de tener representaciones respaldadas por la base de datos de sus atributos.

Rails ofrece exactamente este tipo de solución: la Modelo activo-que es como un modelo normal pero sin las tablas. Proporciona exactamente la misma forma fácil de validación y casi todas las demás funciones enviadas con ActiveRecord. Le ayuda a mantener la estructura de la aplicación consistente, ya que de todos modos está utilizando modelos para representar objetos en su aplicación, las rutas están disponibles de forma gratuita y la creación de formularios es tan fácil como antes con form_for.

Vamos a crear una nueva aplicación primero

En este paso generaremos una aplicación ficticia para jugar durante este tutorial..

Paso 1: Edificio

Inicia tu terminal y escribe estos comandos para crear una nueva aplicación:

# Crear una aplicación de Rails básica rails new tableless cd tableless # Create a Controller con solo nuevo, create & success Las acciones rails generan feedbacks de controlador new create success --skip-route # Create a Model rails generan modelo feedback nombre: cadena email: cadena dirección : mensaje de cadena: sugerencia de texto: texto 

Así es como tu Estructura de directorios veré.

Paso 2: Edición

Aquí le proporcionaré los fragmentos de código para todos los archivos que necesita completar. El código es bastante autoexplicativo. Puedes descargar esta aplicación desde el repositorio de GitHub vinculado a esta publicación o seguir mis pasos para crear una por ti mismo..

→ / config /rutas.rb

recursos: feedbacks,: only => [: new,: create] get 'feedbacks / success' => 'feedbacks # success', como:: success

→ /app/views/feedbacks/success.html.erb

<%= notice %>


<%= link_to 'Submit New Feedback', new_feedback_path %>

→ / app / views / feedbacks /new.html.erb 

Nuevo feedback

<%= form_for(@feedback) do |f| %> <% if @feedback.errors.any? %>

<%= pluralize(@feedback.errors.count, "error") %> prohibió que se guardara esta retroalimentación:

    <% @feedback.errors.full_messages.each do |message| %>
  • <%= message %>
  • <% end %>
<% end %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :address %>
<%= f.text_field :address %>
<%= f.label :message %>
<%= f.text_area :message %>
<%= f.label :suggestion %>
<%= f.text_area :suggestion %>
<%= f.submit %>
<% end %> <%= link_to 'Back', feedbacks_path %>

→ /app/controllers/feedbacks_controller.rb

clase FeedbacksController < ApplicationController def new @feedback = Feedback.new end def create @feedback = Feedback.new(feedback_params) respond_to do |format| if @feedback.save format.html  redirect_to success_path, notice: 'Feedback was successfully submitted.'  else format.html  render :new  end end end def success end private def feedback_params params.require(:feedback).permit(:name, :email, :address, :message, :suggestion) end end

→ / app /modelos / feedbacks.rb

Comentarios de clase < ActiveRecord::Base # fields validation for the database. validates :name, presence: true validates :email, presence: true, length: in:5… 255 validates :address, presence: true validates :message, presence: true validates :suggestion, presence: true end

Paso 3: Implementación

Para implementarlo en su servidor local, primero debe ejecutar los siguientes comandos para crear la base de datos en su sistema.

cd sin tablas / rastrillo db: migrate 

Si ha seguido el tutorial hasta aquí, el comando anterior debería crear una base de datos sqlite3 de forma predeterminada. Para cambiarlo, puedes saltar a database.yml-Por el bien de este tutorial, iré con sqlite3.

Ahora corre rieles en su terminal y debería ver algo similar a esto.

Y con esto deberías estar ejecutando exitosamente una aplicación ficticia..

Paso 4: Pruebas

Ahora es el momento de probar lo que acabamos de crear. Pulsa esta ruta en tu navegador para comprobar si todo funciona bien: http: // localhost: 3000 / feedbacks / new

Deberías ver un formulario como el de arriba. Ahora presione el botón enviar sin completar ningún campo para verificar si las validaciones funcionan bien.

Genial. Debería ver seis errores de validación, como el anterior. Ahora podemos intentar rellenar los valores adecuados y enviar el formulario..

Deberías ver algo similar en tu pantalla. Vamos a revisar la base de datos para el registro que acabamos de ingresar. 

Abre tu Terminal, Vaya al directorio de su proyecto y escriba los comandos a continuación.

  • rieles db para iniciar el cliente de base de datos en su consola.
  • SQLite> .tables para enumerar todas las tablas en su base de datos (DB está seleccionada por defecto).
  • SQLite> .headers en para mostrar el Nombres de columnas en tus resultados.
  • SQLite> select * from feedbacks; Para ver todos los comentarios en la base de datos..

Y aquí podemos ver los comentarios guardados con éxito en la base de datos. Si miras los registros, también puedes encontrar el INSERTAR consulta.

Y con esto nuestra prueba ha terminado. Ahora que todo parece estar funcionando bien, vamos a la solución..

La solución

Paso 1: Implementación 

Para implementar Modelo activo, Lo primero que debe hacer es eliminar la herencia del modelo de realimentación para < ActiveRecord::Base Como no queremos que este modelo tenga una base de datos de back-end. 

Tan pronto como hagamos esto, nuestro formulario ya no funcionará, ya que los validadores son proporcionados por ActiveRecord. Pero añadiendo incluye ActiveModel :: Modelo en la siguiente linea deberia restaurar todo.

Tu modelo debería verse así ahora..

Los comentarios de la clase incluyen ActiveModel :: Modelo 

Lo segundo es agregar. attr_accessor para generar los captadores y definidores para todos los atributos, como este.

attr_accessor: nombre, correo electrónico, dirección, mensaje, sugerencia

Ahora el resultado final del modelo debería verse así..

Los comentarios de la clase incluyen ActiveModel :: Model attr_accessor: name,: email,: address,: message,: sugerencias # validación de campos para la base de datos. valida: nombre, presencia: verdadero valida: correo electrónico, presencia: verdadero, longitud: en: 5… 255 valida: dirección, presencia: verdadero valida: mensaje, presencia: verdadero valida: sugerencia, presencia: verdadero fin

Arreglar el modelo no es suficiente para que nuestra aplicación se comporte como queremos. El controlador aún espera guardar el objeto de datos recibido en la base de datos en el crear método. @ feedback.save no funcionará, ya que no tenemos una base de datos de fondo para guardar los nuevos comentarios.

Podemos solucionar este problema cambiando @ feedback.save dentro @ feedback.valid? ya que solo estamos realizando las validaciones en nuestros modelos ahora, y en función de este evento de éxito, puede realizar cualquier tarea preferida dentro de este bloque de código, es decir, enviar notificaciones, enviar correo electrónico o registrar eventos, etc..

clase FeedbacksController < ApplicationController def create @feedback = Feedback.new(feedback_params) respond_to do |format| if @feedback.valid? # Something interesting can be done here # - send notifications # - send email # - log events format.html  redirect_to success_path, notice: 'Feedback was successfully submitted.'  else format.html  render :new  end end end

Paso 2: Pruebas

Vamos a rehacer las pruebas que realizamos anteriormente..

Golpea la ruta http: // localhost: 3000 / feedbacks / new y enviarEl formulario sin rellenar ningún campo. Todas las validaciones deberían funcionar como antes.

Genial. Ahora podemos intentarlo enviando el formulario con valores válidos..

Y aquí van, el mismo mensaje de éxito..

Ahora lo último que necesitamos revisar es la base de datos. 

Para eso, abre tu Terminal, Vaya al directorio de su proyecto y escriba los comandos a continuación.

  • rieles db para iniciar el cliente de base de datos en su consola.
  • SQLite> .tables para enumerar todas las tablas en su base de datos (DB está seleccionada por defecto).
  • SQLite> .headers en para mostrar el Nombres de columnas en tus resultados.
  • SQLite> select * from feedbacks Para ver todos los comentarios en la base de datos..

Y esta vez, dado que nuestro modelo no está respaldado con ninguna tabla de base de datos, no encontrará los nuevos valores enviados en la tabla.

Si revisa los registros de su consola, tampoco vemos el INSERTAR consulta más.

Conclusión

Así que con esto hemos terminado con el ActiveModel, y vimos lo fácil que es crear un modelo sin tablas. ActiveModel está en grandes mejoras, por lo que puede esperar algunos cambios en las próximas versiones de Rails. 

Acabamos de utilizar las validaciones y las asignaciones de atributos en este tutorial para mantener las cosas simples y claras. Pero eche un vistazo en el directorio que contiene el código de ActiveModel en GitHub.

Podemos ver en la lista que ActiveModel también incluye clases para métodos de atributos, serialización, devoluciones de llamada y seguimiento sucio, entre otras cosas. De esta manera, puedes estar atento a las próximas funciones y también familiarizarte con otros..