Read my latest article: 8 things I look for in a Ruby on Rails app (posted Thu, 06 Jul 2017 17:59:00 GMT)

Using MacPorts Ruby and Rails after Upgrading to OS X Leopard

Posted by Sat, 27 Oct 2007 10:43:00 GMT

If you previously followed my article, Installing Ruby on Rails and PostgreSQL on OS X, second edition and are now upgrading to OS X Leopard, you’ll want to make a few adjustments to your setup.

First of all, it’s great that Apple has decided to provide Ruby on Rails out of the box.


~ > gem list rails                                                                                                                                                                   
  *** LOCAL GEMS ***

  rails (1.2.3)
      Web-application framework with template engine, control-flow layer,
      and ORM.
How many gems does it come with?

~ > gem list|grep '^[a-z]'|wc -l                                                                                                                                                     
      29

It’s really great that Apple shipped Leopard pre-installed with 29 gems, especially if you don’t have your entire Rails stack setup already. In my case and for those that have followed my installation process, you don’t need to switch over to this new development stack (yet). I have a lot of time invested in my fully-functionaly MacPorts installation process (PostgreSQL, MySQL, RMagick, Subversion, Git, etc. Since this all working fine on my machine, I’m not ready to make the switch to Apple’s installation.

Don’t Fix it… if it’s not broken!

So, the the first thing that I did was modify my PATH environment variable, which has /usr/bin as the first path that it’ll look at when you try to run commands like ruby, mongrel_rails, gem, etc. You’ll want to modify this and prepend /opt/local/bin: to the front of PATH in your shell configuration. If you’re using bash, this would be… ~/.bashrc. If you’re using zshell like me, ~/.zshrc.

Now, when you start a new Terminal and run gem list, you’ll see all of the gems that you already have installed.


~ > gem list rails                                                                                                                                   < new-host

*** LOCAL GEMS ***

rails (1.2.5, 1.2.4, 1.2.3, 1.1.6)
    Web-application framework with template engine, control-flow layer,
    and ORM.

Back to my happy gems…


~ > gem list|grep '^[a-z]'|wc -l                                                                                                                                                              < new-host
      72

Great! Now I can get back to work and spend time playing with the new features in Finder, Mail.app, and iChat instead of installing all of the software dependencies that our development projects have. :-)

Q&A: ActiveRecord Observers and You

Posted by Sat, 28 Apr 2007 22:28:00 GMT

Yesterday, I wrote a short post titled, Observers Big and Small, about using Observers in your Rails applications.

The following questions were raised in the comments.

When should I use an Observer?

Eric Allam asks…

“Why not just use ActiveRecord callback hooks instead of Observers? Are Observers more powerful or is it just a matter of preference?”

Eric, this is an excellent question. I’d say that a majority of the time, using the ActiveRecord callbacks 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’s take a recent problem that we used an observer to solve.

Graeme is working on implementing Ferret into a project that we’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’ callbacks, but this violates the DRY[1] principle. So, we created an Observer, which observes each of the models that need these methods to be called. In fact, as far as we’re concerned, the fact that we’re indexing some of its data, is none of its business. We only want our models to be concerned with that they’re designed to be concerned about. We may opt to change our indexing solution in the future and we’d just need to rethink that at the Observer level and not change anything about the business logic in our models.

This is the sort of scenario when using an Observer makes great sense in your application.

Logging from an Observer

Adam R. asks…

“I’d also like the ability to use the logger from within an observer, but that’s another issue.”

I assume that you are referring to the logger method? I always forget to even use that method. I do know that the following works just fine in an Observer.


class IndexObserver < 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  

This will output to your log file without any problem.

This reminded me of when I used to want to log from Unit Tests.

(few minutes later)

Okay, I just attempted to use logger from an Observer and you’re right… it doesn’t currently work. There is a simple fix though, just extend ActiveRecord::Observer to add a logger method like so and require it in config/environment.rb (much like I did in with unit tests).


# lib/observer_extensions.rb
class ActiveRecord::Observer
  def logger
    RAILS_DEFAULT_LOGGER
  end
end

This will give you a solution to that problem.


class FooObserver < 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  

Observers Spy for Us

Most often, I look at Observers as being the guys that I hire to spy on my models. I don’t want my models to know that they’re being spied on and I’d like to keep it that way. They don’t solve all of our problems and it’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’ve had the same things occurring in our model’s callbacks.

If you have other questions related to Observers, feel free to let me know. If you’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.

Related Posts

1 Don’t Repeat Yourself

Do Your Views in Ruby on Rails need a cleaning service?

Posted by Wed, 28 Mar 2007 02:55:00 GMT

I’ve been working on a project with Graeme, and we’re spending some time cleaning up some RHTML views.

He posted an article earlier, titled, Dirty Views? Clean them up!, where he asks the following.

“I am also looking for more information on best practices with views in Rails. There doesn’t seem to be much information on the subject.”

We’re starting to re-evaluate how we approach our views and are curious what other teams are doing… especially if you have a team thats approx 1/2 designers… 1/2 developers per project. We’ll be reviewing some of the other options for the View layer over the coming week(s) and welcome any suggestions/insight to this area of Rails… head over to Graeme’s blog and share your thoughts. :-)