# I need to send an email when something happens in my model

**URL:** <https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864>\
**Category:** Rails\
**Created:** [April 15, 2006, 5:54am UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864 "2006-04-15T05:54:09Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 5:54am UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/1 "2006-04-15T05:54:09Z")

</div>

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/HowtoUseUrlHelpersWithActionMailer](http://wiki.rubyonrails.com/rails/pages/HowtoUseUrlHelpersWithActionMailer)  
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?

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 7:46am UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/2 "2006-04-15T07:46:52Z")

</div>

The best way to handle this is using observers.  
[http://rubyonrails.com/rails/classes/ActiveRecord/Observer.html](http://rubyonrails.com/rails/classes/ActiveRecord/Observer.html)

An excellent example of observers is present in Rick O.'s  
(technoweenie) act\_as\_authenticated plugin.

Best,

Raja

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 8:44am UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/3 "2006-04-15T08:44:25Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 2:05pm UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/4 "2006-04-15T14:05:57Z")

</div>

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](http://9cays.com)

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 2:12pm UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/5 "2006-04-15T14:12:10Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 3:10pm UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/6 "2006-04-15T15:10:41Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 3:36pm UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/7 "2006-04-15T15:36:07Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 4:50pm UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/8 "2006-04-15T16:50:32Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [April 15, 2006, 3:41pm UTC](https://www.ruby-forum.com/t/i-need-to-send-an-email-when-something-happens-in-my-model/57864/9 "2006-04-15T15:41:30Z")

</div>

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
