2009-02-03 14 views
18

El envío de un correo electrónico generalmente se invoca después de una acción en un modelo, pero el correo electrónico en sí es una operación de visualización. Estoy buscando cómo piensas sobre qué pregunta (s) debes hacerte para determinar dónde poner el método de acción llamada de correo. - mal acoplamiento de las preocupaciones relacionadas pero separadasMejores prácticas de ActionMailer: ¿Método de llamada en el modelo o el controlador?

  • En un método de modelo:

    que he visto/los utilizaron?

  • En una devolución de llamada en el modelo (como after_save): la mejor separación hasta donde puedo decir con mi nivel actual de conocimiento.
  • En la acción del controlador, simplemente se siente mal, pero ¿hay situaciones en las que esta sea la forma más inteligente de estructurar el código?

Si quiero saber cómo programar, tengo que pensar como un programador, por lo que aprender a pensar a través de soluciones de programación particulares vale la pena meses de codificación por mi cuenta de forma aislada. ¡Gracias!

Respuesta

12

respuesta tardía, pero quiero racionalizar sobre el tema:

Por lo general, en una aplicación web, que desea enviar mensajes de correo electrónico, ya sea como una reacción directa a un cliente. O como una tarea de fondo, en caso de que estemos hablando de un tipo de boletín de noticias/correo de notificación.

El modelo es básicamente un mapeador de almacenamiento de datos. Su lógica debe encapsular la gestión/comunicación de datos con el manejo del almacenamiento de datos. Por lo tanto, insertar una lógica que no se relaciona con ella es un poco complicado y, en la mayoría de los casos, incorrecto. Tomemos el ejemplo: el usuario registra una cuenta y debe recibir un correo electrónico de confirmación. En este caso, podría decirse que el correo electrónico de confirmación es un efecto directo de la creación de una nueva cuenta. Ahora, en lugar de hacerlo en la aplicación web, intente crear un usuario en la consola. Suena mal para activar una devolución de llamada en ese caso, ¿verdad? Entonces, la opción de devolución de llamada se rayó. ¿Deberíamos escribir el método en el modelo? Bueno, si se trata de un efecto directo de una acción/entrada del usuario, entonces debe permanecer en ese flujo de trabajo. Lo escribiría en el controlador después de que el usuario se haya creado con éxito. Directamente. Replicar esta lógica en el modelo que se llamará en el controlador de todos modos agrega modularidad innecesaria, y la dependencia de un modelo de registro activo de Action Mailer. Trate de considerar compartir el modelo en muchas aplicaciones, en las que algunas de ellas no quieran usar Action Mailer. Por las razones indicadas, soy de la opinión de que las llamadas de correo deben estar donde tengan sentido, y generalmente el modelo es no ese lugar. Trata de darme ejemplos donde sí lo haga.

+1

¿He leído mal o te has equivocado? "Lo escribiría en el controlador después de que el usuario se haya creado correctamente. Directamente". luego, más tarde "Por las razones expresadas, soy de la opinión de que las llamadas de correo deben ser donde tengan sentido, y generalmente el modelo es ese lugar". – Cameron

+1

ahahah, error de escritura! :) thx para la corrección. – ChuckE

+0

_Later_ comentario, pero aquí hay un ejemplo que podría tener sentido en el modelo: cuando se activa un correo electrónico después de un _status_ cambio. Por ejemplo, si un usuario está bloqueado (por ejemplo, cambia 'status' a' locked') debería recibir un correo electrónico, sin importar cómo se bloqueó. ¿Qué piensas? – Gerry

4

Bueno, depende.

He utilizado todas esas opciones y su punto acerca de '¿por qué debería poner esto?' es bueno.

Si es algo que quiero que ocurra cada vez que se actualiza un modelo de cierta manera, entonces lo pongo en el modelo. Tal vez incluso en una devolución de llamada en el modelo.

A veces solo está ejecutando un informe; no hay actualización de nada. En ese caso, normalmente tengo un recurso con una acción de índice que envía el informe.

Si la aplicación de correo no está realmente relacionada con el modelo que se está modificando, podría ver que se trata de una devolución de llamada. No hago eso muy a menudo. Sería más probable que todavía lo encapsulara en el modelo. Lo he hecho, solo que no muy seguido.

1

Soy consciente de que ha pasado un tiempo pero las mejores prácticas nunca mueren, ¿verdad?:)

Email es por definición, comunicación asíncrona (excepto el correo electrónico de confirmación, pero incluso esta debería ser una mejor práctica para dejar un retraso antes de tener que confirmar).

Por lo tanto, en mi opinión, la forma más lógica para enviarlo es:

  • en una acción de fondo (usando Sidekiq o delayed_job)
  • en un método de devolución de llamada: "oye esta acción se realiza con éxito, tal vez podamos decirle al mundo ahora? "

problema en Rails es que es no demasiadas devoluciones de llamada (como en JS, por ejemplo): Yo personnaly encontrarlo sucio para tener un código como:

after_save :callback 

def callback 
    if test_that_is_true_once_in_the_objects_life 
    Mailer.send_email() 
    end 
end 

lo tanto, si usted realmente quiere piense como un programador, la idea sería establecer algún sistema de devolución de llamada personalizado en su aplicación.

Por ejemplo.

def run_with_callback(action, callback_name) 
    if send(action) 
    delay.send(callback_name) 
    end 
end 

O incluso creating an event system in your app habría una solución decente.

Pero al final esas soluciones son bastante caros en el tiempo para que las personas terminan en marcha escribirlo en línea después de la acción

def activate 
    [...] 
    user.save 
    Mailer.send_mail 
    respond_to 
    [...] 
end 

que es el modo más íntimo de devolución de llamada en la programación síncrona y los resultados que tienen los anuncios publicitarios llaman en todas partes (en Model y en Controller).

0

Hay varias razones por las que los controladores son un buen lugar para los anuncios publicitarios:

  • Los correos electrónicos que no tienen nada que ver con un modelo.
  • Si sus correos electrónicos dependen de varios modelos que no se conocen entre sí.
  • Extraer modelos a una API no debe significar la reimplementación de anuncios publicitarios.
  • Contenido de la aplicación de correo determinada por variables de solicitud que no desea pasar al modelo.
  • Si su modelo de negocio requiere una gran cantidad de correos electrónicos diferentes, las devoluciones de llamada modelo se pueden acumular.
  • Si el correo electrónico no depende del resultado de los cálculos del modelo.
Cuestiones relacionadas