Hola gente, a ver si a alguien se le ocurre qué puede estar sucediendo
aquí…
Estamos implementando un sistema de mensajería interna para una
comunidad de usuarios. Básicamente el sistema lo que hace es que un
administrador para enviar un mensaje a todos los usuarios, crea un
objeto SentMessage…
sent_message = SentMessage.create(:subject => ‘hola amigos’, :body =>
‘solo queremos saludaros’)
y después se ejecuta un metodo que se encarga de crear un
ReceivedMessage para todos los usuarios:
sent_message.create_receiveds_for_all_users
Este método simplemente hace un bucle y crea a cada usuario un
ReceivedMessage con los textos del SentMessage:
class SentMessage < ActiveRecord::Base
(…)
def create_receiveds_for_all_users
User.find(:all).each do |recipient|
recipient.received_messages.create( :subject => self.subject,
:body =>
self.body)
end
end
end
Como el bucle de usuarios puede llevar mucho rato si hay muchos
usuarios (ahora estamos probando con 50.000 y lo hace a un ritmo de
1.900 inserts por minuto), la llamada a este metodo la hacemos a
través de starling. O sea, en lugar de
sent_message.create_receiveds_for_all_users
hacemos:
sent_message.push(‘create_receiveds_for_all_users’)
usando la sintaxis del genial plugin de @fesplugas, simplified_starling
[1]
Y hasta aquí todo funciona estupendo.
El problema viene cuando queremos que además, cuando a un usuario se
le crea un ReceivedMessage en su inbox, se le envíe además una
notificación por email. Para ello lo que hacemos es crearnos un
mailer, ReceivedMessageMailer, y un observer, ReceivedMessageObserver,
que, en after_create, se encarga de enviar el email al usuario.
Si lo hacemos sin starling todo funciona bien:
sent_message.create_receiveds_for_all_users
pero si lo hacemos a través de starling, hace todo pero ignora lo del
mailer. Es como si el observer no existiera, no hace nada ni da
ningúnmensaje de error:
sent_message.push(‘create_receiveds_for_all_users’)
Así que lo que probamos es a no usar un observer, sino directamente a
ponerlo con after_create en el modelo ReceivedMessage. Y pasa lo
mismo: directamente funciona, pero a través de starling, lo ignora
como si no ejecutara el callback.
Y para probar a ver si fuera que starling no lanza callbacks, podemos
la llamada al mailer directamente dentro del método:
def create_receiveds_for_all_users
User.find(:all).each do |recipient|
received_message = recipient.received_messages.create( :subject
=> self.subject,
:body =>
self.body)
ReceivedMessageMailer.deliver_notification(received_message)
end
end
quitando los callbacks de antes y… pasa exactamente lo mismo. Sin
starling funciona bien, pero con starling no hace nada con el mailer,
sin mensaje de error, solo que lo ignora.
Así que aquí van mis dudas:
- starling ignora observers?
- starling ignora callbacks?
- starling ignora mailers?
- necesito echarme una siesta?
Como nota aclaratoria, para el envío de mails usamos ARMailer, o sea,
que los mailers heredan de ActionMailer::ARMailer… Por si a alguien
le suena que haya incompatibilidad entre starling y ARMailer… Pero
si lo hacemos directamente con ActionMailer estandar, hace lo mismo, o
sea, nada.
Y para más info, usamos Rails 2.0.2.
Gracias por su colaboración, ciudadanos.
[1] http://github.com/fesplugas/simplified_starling/tree/master