2010-03-31 8 views
10

Sé preguntas similares han sido respondidas antes - como por ejemplo:Rieles: controlador flaco vs. modelo de grasa, o debería hacer mi controlador anoréxico?

  • dónde debería ir la lógica
  • , donde hay que hacer ciertas tareas, etc.

Pero tengo una pregunta más específica - ¿Cómo Hasta ahora debería tomar este axioma: Mantenga su controlador delgado, ¡haga que su modelo gorda!

Aquí se muestra un ejemplo:

Por ejemplo digamos que tienen múltiples fuentes de datos de verificación. Un buen ejemplo sería un número VIN - Puedo verificarlo en contra, fuente de datos del fabricante, fuente de datos del DMV, también mis bases de datos locales - para ver lo que tengo registrado. Así que tengo un modelo llamado Vin y vins_controller. Dentro del modelo que tengo 5 métodos:

  • check_against_local_db
  • check_against_dmv
  • check_against_car_maker_1
  • check_against_car_maker_2, etc.

en mi controlador de acuerdo con el resto del mundo del espectáculo, la acción - Tengo una declaración de caso simple que mira los parámetros [: fuente], y en función de la fuente especificada - llamará al método de verificación específico.

Ahora aquí está la pregunta: ¿Debo dejar la lógica que gobierna qué fuente de datos llamar en el controlador o debo moverlo al modelo y luego en el controlador simplemente hacer algo como check_vin (source, vin)?

¿Debo hacer que mi controlador sea anoréxico?

EDITAR

estoy cambiando a esta respuesta oficial de @ Jay-Godse (gracias - en el momento que era una buena respuesta). Las cosas han cambiado mucho desde 2010 y esta pregunta todavía tiene algunas opiniones, por lo que espero que esto apunte a algunas personas en la dirección correcta y les ayude a organizar su código correctamente.

Trailblazer gem aborda los problemas planteados en la pregunta realmente bien.

Respuesta

2

Debe dar Trailblazer una oportunidad. Este es un marco delgado sobre Rails (en realidad, se ejecuta con todos los frameworks de Ruby), presenta una capa de servicio, objetos de formulario, direccionamiento indirecto entre la persistencia y el código de dominio, y así sucesivamente.

Realmente ayuda a mantener todos los componentes del software delgados ya que le da más capas de abstracción que hacen que sea mucho más fácil averiguar dónde poner qué.

Por ejemplo, ¿por qué presionaría su lógica de validación en el controlador y el modelo cuando tiene un objeto de formulario para eso?

+1

Estoy cambiando esto a una respuesta oficial. Las cosas han cambiado mucho desde 2010 y esta pregunta todavía tiene puntos de vista, así que espero que esto apunte a algunas personas en la dirección correcta. Trailblazer aborda los problemas planteados en la pregunta realmente bien. – konung

4

Pondría la lógica en mi modelo, especialmente si estoy TDD'ing (y siempre uso TDD, excepto cuando no lo hago). La prueba del modelo suele ser mucho más fácil que la prueba del controlador.

+0

También significa que no necesita validar en cada uno de sus controladores. – SeanJA

3

Me gusta plantear preguntas como esta pensando en la responsabilidad. ¿Qué es en este caso "responsable" de verificar el VIN? El modelo. El controlador simplemente está allí para pasar los parámetros ... para "controlar" según la entrada del usuario.

Si no está del todo claro, piénselo de esta manera: ¿dónde colocar este código causará la menor cantidad de impacto si necesita ser reutilizado? Digamos ... si dos acciones diferentes en dos controladores diferentes necesitan verificar un VIN, ¿qué debería hacerse?Si dejó este código en el controlador, esencialmente tendría que duplicarlo también en el nuevo controlador, pero si lo hubiera colocado en el modelo, simplemente llamaría al método check_vin del nuevo controlador y no tendría código. la duplicación sería necesaria. Al asignar responsabilidades donde tienen más sentido, ha mejorado la reutilización de su código.

+0

Me gusta decir "El código del controlador es para clientes HTTP" ... ¿Qué sucede si estás (hipotéticamente) reutilizando el modelo en una aplicación de escritorio? Eso generalmente endereza hacia dónde debería ir el código. –

19

Hay un viejo dicho,

estructuras de datos inteligentes y el código mudo funciona mucho mejor que la otra manera alrededor .

Todo lo que ha descrito es acerca de cómo una parte de los datos se relaciona con otra. Esa es su pista de que la lógica para esas relaciones, incluida la validación, debería estar en el modelo o en la capa de la base de datos.

Un controlador anoréxico es un signo de datos bien diseñados (¿inteligentes?). Mi experiencia me dice que cuanto más esfuerzo dediques al diseño de tus datos, menos código tendrás que escribir en general.

Los controladores son mejores para analizar entradas, llamar a los modelos apropiados y luego formatear las salidas.

+0

Muy interesante. Me alegra haber leído esto ... y también haber buscado el origen de ese dicho: [La Catedral y el Bazar] (http://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar) – dmonopoly

+0

+1 por " * Los controladores son los mejores para analizar entradas, llamar a los modelos apropiados y luego formatear las salidas. * " – Ish

2

Es responsabilidad del controlador "analizar" params, pero la validación debe hacerse en el modelo.

que haría algo como esto en el controlador:

@my_model = MyModel.new(:source => params[:source] ...) 
if(@my_model.valid?) 
    # treat valid model here (i.e. save the model and redirect to show) 
else 
    # treat validation error here (usually throw an error) 
end 

Su controlador será en realidad sólo "flaco". Para los controladores verdaderamente "anoréxicos", es posible que desee echar un vistazo a inherited_resources o resource_this. En algunos casos, estos le darán un controlador de 3 líneas, implementando toda la pila RESTful.

Cuestiones relacionadas