Robby on Rails: Observers Big and Smallthoughts.sort_by{|t| t[:topic]}.collect tag:www.robbyonrails.com,2005:TypoTypo2007-04-27T13:37:05-04:00Robby Russellurn:uuid:ebff46c4-4af0-4e95-b950-72023fff7d0a2007-04-27T13:15:00-04:002007-04-27T13:37:05-04:00Observers Big and Small<p>My colleague, <a href="http://blog.garyblessington.us">Gary</a>, keeps a stack of Ruby and Rails books on his desk and was implementing an Observer into a client project. It appears that the Agile Web Development with Rails book is still encouraging people to do the following in order to load an Observer.</p>
<pre><code>
# app/models/flower_observer.rb
class FlowerObserver < ActiveRecord::Observer
observe Flower
def after_create(model)
# model.do_something!
end
end
# controller(s)
class FlowerController < ApplicationController
observer :flower_observer
end
</code></pre>
<p>What is wrong with this approach?</p>
<p>Well, in order for your Observer to be used, the model(s) callbacks that it is observing need to be triggered through a controller. If you end up writing any scheduled rake tasks, your observer will not be called. In my opinion, the controller shouldn’t know this much about the model. In fact, the model doesn’t even really know about it’s observer… so why should a controller?</p>
<p>This was actually changed a long time ago (<a href="http://www.robbyonrails.com/articles/2006/02/27/where-did-my-observer-go">I previously blogged about a different solution here</a>) and the Rails docs for <a href="http://api.rubyonrails.org/classes/ActiveRecord/Observer.html">ActiveRecord::Observer</a> are currently correct.</p>
<h2>Observers in the Environment</h2>
<p>If you open up a recent version of <code>config/environment.rb</code>, you notice in the comments the following.</p>
<pre><code>
# Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector
</code></pre>
<p>Take a moment to go ahead and specify which observer(s) you’d like to load into your Rails environment.</p>
<pre>config.active_record.observers = :flower_observer</pre>
<p>Then you can remove your observer calls in all your controllers, because that’s not where you should be defining them.</p>
<p>Also, if you’re not using Observers yet, I’d really encourage you to consider reading up on them and giving them a try.</p><p>My colleague, <a href="http://blog.garyblessington.us">Gary</a>, keeps a stack of Ruby and Rails books on his desk and was implementing an Observer into a client project. It appears that the Agile Web Development with Rails book is still encouraging people to do the following in order to load an Observer.</p>
<pre><code>
# app/models/flower_observer.rb
class FlowerObserver < ActiveRecord::Observer
observe Flower
def after_create(model)
# model.do_something!
end
end
# controller(s)
class FlowerController < ApplicationController
observer :flower_observer
end
</code></pre>
<p>What is wrong with this approach?</p>
<p>Well, in order for your Observer to be used, the model(s) callbacks that it is observing need to be triggered through a controller. If you end up writing any scheduled rake tasks, your observer will not be called. In my opinion, the controller shouldn’t know this much about the model. In fact, the model doesn’t even really know about it’s observer… so why should a controller?</p>
<p>This was actually changed a long time ago (<a href="http://www.robbyonrails.com/articles/2006/02/27/where-did-my-observer-go">I previously blogged about a different solution here</a>) and the Rails docs for <a href="http://api.rubyonrails.org/classes/ActiveRecord/Observer.html">ActiveRecord::Observer</a> are currently correct.</p>
<h2>Observers in the Environment</h2>
<p>If you open up a recent version of <code>config/environment.rb</code>, you notice in the comments the following.</p>
<pre><code>
# Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector
</code></pre>
<p>Take a moment to go ahead and specify which observer(s) you’d like to load into your Rails environment.</p>
<pre>config.active_record.observers = :flower_observer</pre>
<p>Then you can remove your observer calls in all your controllers, because that’s not where you should be defining them.</p>
<p>Also, if you’re not using Observers yet, I’d really encourage you to consider reading up on them and giving them a try.</p>
Gordon Yeongurn:uuid:a320bb01-a496-43f4-bfaa-656ea672d6dc2010-01-19T16:43:46-05:002010-02-06T07:56:12-05:00Comment on Observers Big and Small by Gordon Yeong<p>hi, there :)
and <a href="http://api.rubyonrails.org/" rel="nofollow">http://api.rubyonrails.org/</a>/</p>
<pre><code>Good post :)
I refered to <a href="http://guides.rubyonrails.org/action_mailer_basics.html" rel="nofollow">http://guides.rubyonrails.org/action_mailer_basics.html</a></code></pre>
<p>I am a bit unclear about observers.</p>
<p>Consider the set up below:</p>
<p>model/part_mailer.rb
—-—-—-—-—--
class PartMailer < ActionMailer::Base
@admin_email = ‘<a href="mailto:admin@sample.com" rel="nofollow">admin@sample.com</a>’
@from_email = ‘<a href="mailto:admin-sales@sample.com" rel="nofollow">admin-sales@sample.com</a>’</p>
<pre><code>def created_succesfully(part)
recipients user.email, @admin_email
from @from_email
subject "MyApp - New part created."
body :user => user
end</code></pre>
<p>model/part_observer.rb
—-—-—-—-—-——</p>
<p>class PartObserver < ActiveRecord::Observer
def after_create(part)
PartMailer.deliver_created_succesfully(part)
end
end</p>
<p>It looks as if I can only pass in the object of the given class into
the observer.
In the case above, ‘part’ is the only one that is being passed by to
deliver_created_successfully
in model/part_observer.rb.
part_mailer.rb)?
I tried looking at the api docs and <a href="http://guides.rubyonrails.org/action_mailer_basics.html" rel="nofollow">http://guides.rubyonrails.org/action_mailer_basics.html</a>
to
no success. Can someone please shed some light into this?</p>
<pre><code>Can I pass more objects to the method, created_successfully (model/</code></pre>
<p>Thanks! :)</p>