BelongsToDemeter

written by trotter on June 10th, 2008 @ 10:30 PM

While playing with Rails the other day, I thought it would be fun if you could get at attributes of a belongs_to association without having to do the whole traverse association and check for nil thing.


# Something like...
@person.group_name  # => "Pizza Fans!" || nil

# Instead of...
@person.group ? @person.group.name : nil # => "Pizza Fans!" || nil

Thinking this would be a fun chance to play with some meta, I threw together BelongsToDemeter, which you can find over on GitHub. It's a rails plugin, but don't expect it to actually install using script/plugin. The code is complete and utter crap, so it's probably best that Rails won't install it. It is slow, and most likely prone to error. Still, it's a fun little thought experiment, and I may decide to clean it up then speed it up if someone tells me they like it.

It does what I explained above and also lets you do fun things like this, which I think are useful when assigning associations through a form:


# Lookup the user 'Bob' by login and assign 
# it to the user association
@character.user               # => nil
@character.user_login = "bob"
@character.user.login         # => "bob"

Anyway, go over to GitHub and check out BelongsToDemeter. When you're done, let me know if you like the concept. After all that, go erase all memory of the implementation details from your mind, they're ugly.

Comments

  • Pat Nakajima on 11 Jun 10:06

    I tend to prefer to use something like Object#try in these cases: http://configurati.com/pages/another-version-of-object-try.
  • Colin on 11 Jun 10:12

    Neat idea! I can think of a few scenarios in my own projects where this would come in handy and prevent some wasted code.
  • Trotter Cashion on 11 Jun 10:49

    Pat, Object.try isn't bad, I just think this reads a little better.
    
    # Less code :-)
    @person.try(:group).try(:name)
    @person.group_name  # => "Pizza Fans!" || nil
    
    @character.user = User.find_by_login('bob')
    @character.user_login = 'bob'
    
    Of course, the second example may be more clear the User.find_by_login way.

Comments are closed

Options:

Size

Colors