En Ruby on Rails Development (o MVC en general), qué regla rápida debo seguir en cuanto a dónde poner la lógica.
Responda afirmativamente: con Do ponga esto aquí , en lugar de No ponga eso allí .
En Ruby on Rails Development (o MVC en general), qué regla rápida debo seguir en cuanto a dónde poner la lógica.
Responda afirmativamente: con Do ponga esto aquí , en lugar de No ponga eso allí .
Respuestas:
MVC
Controlador : ponga aquí el código que tiene que ver con calcular lo que un usuario quiere y decidir qué darles, determinar si están conectados, si deberían ver ciertos datos, etc. Al final, el controlador examina las solicitudes y calcula qué datos (Modelos) mostrar y qué Vistas representar. Si tiene dudas sobre si el código debe ir en el controlador, entonces probablemente no debería. Mantenga sus controladores flacos .
Vista : La vista solo debe contener el código mínimo para mostrar sus datos (Modelo), no debe procesar o calcular mucho, debe mostrar datos calculados (o resumidos) por el Modelo o generados desde el Controlador. Si su Vista realmente necesita hacer un procesamiento que no puede hacer el Modelo o el Controlador, coloque el código en un Ayudante. Una gran cantidad de código Ruby en una vista hace que el marcado de las páginas sea difícil de leer.
Modelo : su modelo debe ser donde reside todo el código que se relaciona con sus datos (las entidades que componen su sitio, por ejemplo, usuarios, publicaciones, cuentas, amigos, etc.). Si el código necesita guardar, actualizar o resumir datos relacionados con sus entidades, póngalo aquí. Será reutilizable en sus Vistas y Controladores.
Para agregar a la respuesta de pauliephonic:
Ayudante : funciones para facilitar la creación de la vista. Por ejemplo, si siempre está iterando sobre una lista de widgets para mostrar su precio, póngalo en un asistente (junto con un parcial para la visualización real). O si tiene un trozo de RJS que no desea saturar la vista, póngalo en una ayuda.
El patrón MVC en realidad solo tiene que ver con la interfaz de usuario y nada más. No debe colocar ninguna lógica empresarial compleja en el controlador, ya que controla la vista, pero no la lógica. El Controlador debe ocuparse de seleccionar la vista adecuada y delegar cosas más complejas al modelo de dominio (Modelo) o la capa empresarial.
El diseño impulsado por dominio tiene un concepto de servicios, que es un lugar en el que pega la lógica que necesita orquestar varios tipos diferentes de objetos, lo que generalmente significa lógica que no pertenece naturalmente a una clase de modelo.
Generalmente pienso en la capa de Servicio como la API de mis aplicaciones. Mis capas de Servicios generalmente se ajustan bastante a los requisitos de la aplicación que estoy creando, por lo tanto, la capa de Servicio actúa como una simplificación de las interacciones más complejas que se encuentran en los niveles inferiores de mi aplicación, es decir, podría lograr el mismo objetivo sin pasar por las capas de Servicio pero tendrías que tirar de muchas más palancas para que funcione.
Tenga en cuenta que no estoy hablando de Rails aquí, estoy hablando de un estilo arquitectónico general que aborda su problema particular.
Explicaciones perfectas aquí ya, una oración muy simple como conclusión y fácil de recordar:
Necesitamos modelos SMART, controladores THIN y vistas DUMB.
La forma de Rails es tener controladores flacos y modelos gordos .
Ponga cosas relacionadas con la autorización / control de acceso en el controlador.
Los modelos tienen que ver con sus datos. Validación, Relaciones, CRUD, Lógica Empresarial
Las vistas tratan de mostrar sus datos. Mostrar y obtener solo entrada.
Los controladores tratan de controlar qué datos van de su modelo a su vista (y qué vista) y de su vista a su modelo. Los controladores también pueden existir sin modelos.
Me gusta pensar en el controlador como un guardia de seguridad / recepcionista que le dirige al cliente (solicitud) al mostrador apropiado donde le hace una pregunta al cajero (ver). El cajero (vista) luego va y obtiene la respuesta de un gerente (modelo), a quien nunca ve. Luego, solicite que regrese al guardia de seguridad / recepcionista (controlador) y espere hasta que se le indique que vaya a otro cajero (vista) que le diga la respuesta que el gerente (modelo) les dijo en respuesta a la pregunta del otro cajero (vista) .
Del mismo modo, si desea decirle al cajero (ver) algo, entonces sucede lo mismo, excepto que el segundo cajero le dirá si el gerente aceptó su información. También es posible que el guardia de seguridad / recepcionista (controlador) le haya dicho que haga una caminata ya que no estaba autorizado a comunicarle esa información al gerente.
Entonces, para extender la metáfora, en mi mundo estereotipado y poco realista, los cajeros (puntos de vista) son bonitos pero con la cabeza vacía y a menudo creen todo lo que les dices, los guardias de seguridad / recepcionistas son mínimamente educados pero no están muy bien informados, pero saben dónde la gente debería y No debería ir y los gerentes son realmente feos y malos, pero saben todo y pueden decir qué es verdad y qué no.
Una cosa que ayuda a separar adecuadamente es evitar el anti-patrón "pasar variables locales del controlador para ver". En lugar de esto:
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
def show
@foo = Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...
Intenta moverlo a un getter que esté disponible como método auxiliar:
# app/controllers/foos_controller.rb:
class FoosController < ApplicationController
helper_method :foo
def show
end
protected
def foo
@foo ||= Foo.find(...)
end
end
#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...
Esto facilita la modificación de lo que se pone en "@foo" y cómo se usa. Aumenta la separación entre el controlador y la vista sin hacerlos más complicados.
foo
y de @foo
son los mismos: ambos tienen un alcance para el par <ControllerClass, request>. Además, al usar la versión getter, puedo cambiar cómo Foo
se encuentra / almacena / almacena en caché ese objeto sin cambiar la forma en que la vista accede a él.
Bueno, de alguna manera depende de con qué tiene que lidiar la lógica ...
A menudo, tiene sentido introducir más cosas en sus modelos, dejando pequeños controladores. Esto garantiza que esta lógica se pueda usar fácilmente desde cualquier lugar donde necesite acceder a los datos que representa su modelo. Las vistas casi no deben contener lógica. Así que realmente, en general, debes esforzarte para que no te repitas.
Además, un poco de google revela algunos ejemplos más concretos de lo que va a dónde.
Modelo: requisitos de validación, relaciones de datos, métodos de creación, métodos de actualización, métodos de destrucción, métodos de búsqueda (tenga en cuenta que no solo debe tener las versiones genéricas de estos métodos, sino que si hay algo que está haciendo mucho, como encontrar personas con rojo cabello por apellido, entonces debes extraer esa lógica para que todo lo que tienes que hacer es llamar al find_redH_by_name ("smith") o algo así)
Vista: Esto debería ser todo sobre el formato de datos, no el procesamiento de datos.
Controlador: Aquí es donde va el procesamiento de datos. Desde Internet: "El propósito del controlador es responder a la acción solicitada por el usuario, tomar cualquier parámetro que el usuario haya establecido, procesar los datos, interactuar con el modelo y luego pasar los datos solicitados, en forma final, a ver."
Espero que ayude.
En términos simples, en general, los Modelos tendrán todos los códigos relacionados con la (s) tabla (s), sus relaciones simples o complejas (piense en ellas como consultas sql que involucran múltiples tablas), manipulación de los datos / variables para llegar a un resultado utilizando la lógica de negocios .
Los controladores tendrán códigos / punteros hacia los modelos relevantes para el trabajo solicitado.
Las vistas aceptarán la entrada / interacción del usuario y mostrarán la respuesta resultante.
Cualquier desviación importante de estos generará una tensión no deseada en esa parte y el rendimiento general de la aplicación puede verse afectado.
Pruebas, pruebas ... Ponga tanta lógica como sea posible en el modelo y luego podrá probarlo correctamente. Las pruebas unitarias prueban los datos y la forma en que se forman al probar el modelo, y las pruebas funcionales prueban la forma en que se enrutan o controlan al probar los controladores, por lo que se deduce que no puede probar la integridad de los datos a menos que estén en el modelo.
j