Forum: Ruby on Rails I need to send an email when something happens in my model..

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Pat M. (Guest)
on 2006-04-15 07:54
(Received via mailing list)
but the model isn't the right place to send mail from.  That just
seems like pretty bad coupling, generating emails from within the
model.  Or is that not a problem?  On top of that, these emails need
to contain links back to my site...which is a bit of a pain in
ActionMailer, but I found directions on
http://wiki.rubyonrails.com/rails/pages/HowtoUseUr...
however I won't be able to pass in an instance of the controller if
I'm generating the emails from the model.

Anyway, when a certain method is called on my model, I want to send an
email out to a bunch of users associated with that model, and have
each email contain a link back to the app.  What's the best way to go
about doing that?
Raja Bhatia (Guest)
on 2006-04-15 09:46
(Received via mailing list)
The best way to handle this is using observers.
http://rubyonrails.com/rails/classes/ActiveRecord/...

An excellent example of observers is present in Rick O.'s
(technoweenie) act_as_authenticated plugin.

Best,

Raja
Pat M. (Guest)
on 2006-04-15 10:44
(Received via mailing list)
It seems like this is only for particular AR methods (save, create,
destroy, etc).  I need to send out an email whenever a specific method
is called.

Pat
Pete Y. (Guest)
on 2006-04-15 16:05
(Received via mailing list)
Instiki has a relatively neat way of solving this that I've also
adopted for my own code. (The Instiki version is much more extensive
than the example that I'm going to give here.)

In the lib directory, I've got a class that looks like this:

   class UrlGenerator
     @@controller ||= nil

     def self.controller=(controller)
       @@controller = controller
     end

     def self.url_for(options)
       @@controller.url_for(options) if @@controller
     end
   end

Then, in a before_filter I call UrlGenerator.controller = self.

Finally, when generating email, I can call UrlGenerator.url_for(...)
to create a URL.

Yes, this is breaking MVC in a way, but I don't feel too bad about
it. Giving the model the ability to generate a URL seems reasonable,
and the URLGenerator class encapsulates that idea while hiding the
rest of the controller.

Pete Y.
http://9cays.com
Larry W. (Guest)
on 2006-04-15 16:12
(Received via mailing list)
Is the method called from the controller or the model? If its the
controller, why not wrap it with another method in the controller and
call
from there?

The more sophisticated approach would just be to implement a
publish/subscribe mechanism of your own.  The simplist approach is to
have
the method call something like:

def signal_event(params, sender)
    subscribers.each{|ea|
        ea.handle_event(params, sender)
}
end

This assumes that the object has a list of subscribers which include the
mail sender. For simplicity you could make params a hash and let the
subscribers read it according to the keys they need.  Normally, you'd
subclass from something that handled publish/subscribe details like
attaching and detatching subscribers, implements signal_event, etc.

You could check the Gang of Four patterns book for other
implementations.
(or google for it)

cheers.
David C. (Guest)
on 2006-04-15 17:10
(Received via mailing list)
On Saturday 15 April 2006 08:05 am, Pete Y. wrote:
>        @@controller = controller
> to create a URL.
>
> Yes, this is breaking MVC in a way, but I don't feel too bad about
> it. Giving the model the ability to generate a URL seems reasonable,
> and the URLGenerator class encapsulates that idea while hiding the
> rest of the controller.

The real problem with this, is that it you'll have tremendous problems
if you
ever try to run in a multi-threaded  environment.  Rails may not run
that way
today, but it's reasonable to expect that it might someday.

David
Andreas S. (Guest)
on 2006-04-15 17:36
Pete Y. wrote:
> Instiki has a relatively neat way of solving this that I've also
> adopted for my own code. (The Instiki version is much more extensive
> than the example that I'm going to give here.)
>
> In the lib directory, I've got a class that looks like this:
>
>    class UrlGenerator
>      @@controller ||= nil
>
>      def self.controller=(controller)
>        @@controller = controller
>      end
>
>      def self.url_for(options)
>        @@controller.url_for(options) if @@controller
>      end
>    end
>
> Then, in a before_filter I call UrlGenerator.controller = self.

Unfortunately this doesn't work when you don't have any controller
instances, e.g. in a daemon that works with the application data for
maintenance, importing data from other sources and stuff like that. I
have this problem with RForum, it's the reason why email notifications
don't work for posts that are received via mailing list.
Pat M. (Guest)
on 2006-04-15 17:41
(Received via mailing list)
Here's what I ended up doing.

I made a new model, Message, which just has two fields - the user_id
and a string which represents a message type.  In the model when the
even occurs, I create a new record.

I then created a new Mailer that has all methods and views that I need
- standard.

Finally I wrote an app which pulls all Message records from the db,
does a case to figure out what it needs to do, delivers the right
message through the mailer, and then deletes the record.

Obie F. blogged about a messaging system his guys came up with,
but I couldn't find any code for that.  When he releases it I'll
probably use that, and just publish messages from within my model.
This is working fine though, so who knows, I might not have a reason
to change to a proper publish/subscribe.

Also one advantage that I realized after doing this is that no fcgi
processes are tied up with the processing of sending a bunch of
emails.  Stick it in the db, have another program that processes the
emails, and I get finer controller over how emails are delivered + my
fcgi processes stay dedicated to web stuff.

Pat
Andreas S. (Guest)
on 2006-04-15 18:50
Pat M. wrote:
> Also one advantage that I realized after doing this is that no fcgi
> processes are tied up with the processing of sending a bunch of
> emails.  Stick it in the db, have another program that processes the
> emails, and I get finer controller over how emails are delivered + my
> fcgi processes stay dedicated to web stuff.

How do you generate URLs in Mails?
This topic is locked and can not be replied to.