<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Robby on Rails: Tag observers</title>
    <link>http://www.robbyonrails.com/articles/tag/observers</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>thoughts.sort_by{|t| t[:topic]}.collect </description>
    <item>
      <title>Q&amp;amp;A: ActiveRecord Observers and You</title>
      <description>&lt;p&gt;Yesterday, I wrote a short post titled, &lt;a href="http://www.robbyonrails.com/articles/2007/04/27/observers-big-and-small"&gt;Observers Big and Small&lt;/a&gt;, about using Observers in your Rails applications.&lt;/p&gt;


	&lt;p&gt;The following questions were raised in the comments.&lt;/p&gt;


	&lt;h2&gt;When should I use an Observer?&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://www.last100meters.com/"&gt;Eric Allam&lt;/a&gt; asks&amp;#8230;&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&lt;em&gt;&amp;#8220;Why not just use ActiveRecord callback hooks instead of Observers? Are Observers more powerful or is it just a matter of preference?&amp;#8221;&lt;/em&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Eric, this is an excellent question. I&amp;#8217;d say that a majority of the time, using the &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html"&gt;ActiveRecord callbacks&lt;/a&gt; in your models is going to work for your situation. However, there are times that you want the same methods to be called through callbacks. For example, let&amp;#8217;s take a recent problem that we used an observer to solve.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://blog.imperialdune.com/"&gt;Graeme&lt;/a&gt; is working on implementing &lt;a href="http://rubyforge.org/projects/ferret"&gt;Ferret&lt;/a&gt; into a project that we&amp;#8217;re developing for a client. With the use of Ferret, we can index and later search through content over several objects into a format that makes sense for our implementation goals. Each time an object is created and updated, we have to update our Ferret indexes to reflect these changes. The most obvious location that we can call our indexing methods is in each models&amp;#8217; callbacks, but this violates the &lt;span class="caps"&gt;DRY&lt;/span&gt;[1] principle. So, we created an Observer, which &lt;em&gt;observes&lt;/em&gt; each of the models that need these methods to be called. In fact, as far as we&amp;#8217;re concerned, the fact that we&amp;#8217;re indexing some of its data, is none of its business. We only want our models to be concerned with that they&amp;#8217;re designed to be concerned about. We may opt to change our indexing solution in the future and we&amp;#8217;d just need to rethink that at the Observer level and not change anything about the business logic in our models.&lt;/p&gt;


	&lt;p&gt;This is the sort of scenario when using an Observer makes great sense in your application.&lt;/p&gt;


	&lt;h2&gt;Logging from an Observer&lt;/h2&gt;


	&lt;p&gt;Adam R. asks&amp;#8230;&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&lt;em&gt;&amp;#8220;I&amp;#8217;d also like the ability to use the logger from within an observer, but that’s another issue.&amp;#8221;&lt;/em&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I assume that you are referring to the &lt;code&gt;logger&lt;/code&gt; method? I always forget to even use that method. I do know that the following works just fine in an Observer.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
class IndexObserver &amp;lt; ActiveRecord::Observer
  observer Article, Editorial, BlogPost, ClassifiedAd

  def after_save(model)
    RAILS_DEFAULT_LOGGER.warn("Every single day. Every word you say. Every game you play. Every night you stay. I'll be watching you.")
    # execute something fun
  end
end  
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This will output to your log file without any problem.&lt;/p&gt;


	&lt;p&gt;This reminded me of when I used to want to &lt;a href="http://www.robbyonrails.com/articles/2006/01/25/rails-logger-and-those-pesky-tests"&gt;log from Unit Tests&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;(few minutes later)&lt;/p&gt;


	&lt;p&gt;Okay, I just attempted to use &lt;code&gt;logger&lt;/code&gt; from an Observer and you&amp;#8217;re right&amp;#8230; it doesn&amp;#8217;t currently work. There is a simple fix though, just extend ActiveRecord::Observer to add a &lt;code&gt;logger&lt;/code&gt; method like so and require it in &lt;code&gt;config/environment.rb&lt;/code&gt; (much like I did in with unit tests).&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# lib/observer_extensions.rb
class ActiveRecord::Observer
  def logger
    RAILS_DEFAULT_LOGGER
  end
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This will give you a solution to that problem.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
class FooObserver &amp;lt; ActiveRecord::Observer
  observer Foo

  def after_save(model)
    logger.warn("I wonder if the #{address.class} knows that I've been watching it all along?")
  end
end  
&lt;/code&gt;&lt;/pre&gt;

	&lt;h2&gt;Observers Spy for Us&lt;/h2&gt;


	&lt;p&gt;Most often, I look at Observers as being the guys that I hire to spy on my models. I don&amp;#8217;t want my models to know that they&amp;#8217;re being spied on and I&amp;#8217;d like to keep it that way. They don&amp;#8217;t solve all of our problems and it&amp;#8217;s easy to overuse them. However, I have found several cases that they made a lot of sense and most of those cases have been where we&amp;#8217;ve had the same things occurring in our model&amp;#8217;s callbacks.&lt;/p&gt;


	&lt;p&gt;If you have other questions related to Observers, feel free to let me know. If you&amp;#8217;re already using Observers, perhaps you could post a comment and/or blog post response with an example of when and how you use Observers in your Rails applications.&lt;/p&gt;


	&lt;h3&gt;Related Posts&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.robbyonrails.com/articles/2007/04/27/observers-big-and-small"&gt;Observers Big and Small&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.robbyonrails.com/articles/2006/02/27/where-did-my-observer-go"&gt;Where did my Observer go?&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://tom-eric.info/archive/2006/10/30/observers-in-ruby-on-rails"&gt;Observers in Ruby on Rails&lt;/a&gt;, Tom Eric&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Don&amp;#8217;t Repeat Yourself&lt;/p&gt;
</description>
      <pubDate>Sat, 28 Apr 2007 17:28:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:587732a9-50fb-476d-b46a-1c10d29c3559</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2007/04/28/q-a-activerecord-observers-and-you</link>
      <category>Ruby on Rails</category>
      <category>Ruby</category>
      <category>Programming</category>
      <category>PLANET ARGON</category>
      <category>activerecord</category>
      <category>observers</category>
      <category>patterns</category>
      <category>q</category>
      <category>a</category>
      <category>logging</category>
      <category>ferret</category>
      <category>graeme</category>
      <category>DRY</category>
    </item>
    <item>
      <title>Observers Big and Small</title>
      <description>&lt;p&gt;My colleague, &lt;a href="http://blog.garyblessington.us"&gt;Gary&lt;/a&gt;, 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.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# app/models/flower_observer.rb
class FlowerObserver &amp;lt; ActiveRecord::Observer
  observe Flower

  def after_create(model)
    # model.do_something!
  end
end

# controller(s)
class FlowerController &amp;lt; ApplicationController
  observer :flower_observer
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;What is wrong with this approach?&lt;/p&gt;


	&lt;p&gt;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&amp;#8217;t know this much about the model. In fact, the model doesn&amp;#8217;t even really know about it&amp;#8217;s observer&amp;#8230; so why should a controller?&lt;/p&gt;


	&lt;p&gt;This was actually changed a long time ago (&lt;a href="http://www.robbyonrails.com/articles/2006/02/27/where-did-my-observer-go"&gt;I previously blogged about a different solution here&lt;/a&gt;) and the Rails docs for &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Observer.html"&gt;ActiveRecord::Observer&lt;/a&gt; are currently correct.&lt;/p&gt;


	&lt;h2&gt;Observers in the Environment&lt;/h2&gt;


	&lt;p&gt;If you open up a recent version of &lt;code&gt;config/environment.rb&lt;/code&gt;, you notice in the comments the following.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  # Activate observers that should always be running
  # config.active_record.observers = :cacher, :garbage_collector
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Take a moment to go ahead and specify which observer(s) you&amp;#8217;d like to load into your Rails environment.&lt;/p&gt;


&lt;pre&gt;config.active_record.observers = :flower_observer&lt;/pre&gt;

	&lt;p&gt;Then you can remove your observer calls in all your controllers, because that&amp;#8217;s not where you should be defining them.&lt;/p&gt;


	&lt;p&gt;Also, if you&amp;#8217;re not using Observers yet, I&amp;#8217;d really encourage you to consider reading up on them and giving them a try.&lt;/p&gt;
</description>
      <pubDate>Fri, 27 Apr 2007 13:15:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ebff46c4-4af0-4e95-b950-72023fff7d0a</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2007/04/27/observers-big-and-small</link>
      <category>Ruby on Rails</category>
      <category>Ruby</category>
      <category>Programming</category>
      <category>activerecord</category>
      <category>development</category>
      <category>rails</category>
      <category>models</category>
      <category>observers</category>
      <category>docs</category>
    </item>
    <item>
      <title>Where did my observer go?</title>
      <description>&lt;p&gt;I was playing around with an application from &lt;code&gt;script/console&lt;/code&gt; and all of a sudden&amp;#8230; my &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Observer.html"&gt;Observers&lt;/a&gt; just stopped working. It took me a while to figure out that when I would call &lt;code&gt;Dispatcher.reset_application!&lt;/code&gt;... it wouldn&amp;#8217;t reload config/environment.rb where I have defined the observers.&lt;/p&gt;


	&lt;p&gt;I really don&amp;#8217;t like that this is the current implementation for invoking Observers and adding them to the controllers is not kosher with my (do-it-in-script-console) approach.&lt;/p&gt;


	&lt;p&gt;The current solution?&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
# app/models/foo_bar.rb
class FooBar &amp;lt; ActiveRecord::Base
end

FooBarObserver.instance
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;... there needs to be a better way!&lt;/p&gt;
</description>
      <pubDate>Mon, 27 Feb 2006 23:05:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:bf47590a-2ccc-4c32-87a6-7b45325f630f</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2006/02/27/where-did-my-observer-go</link>
      <category>observers</category>
      <category>activerecord</category>
      <category>rails</category>
    </item>
  </channel>
</rss>
