ActiveRecord vs. Domain-Specific Method

Posted by yrashk

I had a short discussion on a kind of “philosophic” subject recently. The issue is whether to use ActiveRecord API to manipulate model’s logic, like


@user.friendship.create(:friend => @friend)

or to define simplistic domain-specific methods, like:


@user.add_friend(@friend)
or

@friend.add_to_friends_of(@user)

While first approach has its own benefits (having strict and simple API, just like in RESTful approach), I think that it has two downsides:

1. It’s hardly readable comparing to domain-specific approach. I believe that application’s “language” should be as close to user’s dictionary and semantics. I don’t think users think about adding friends like “oh, I’d like to create friendship with that user!”, it rather sounds “I’d like to add him/her as friend” or something like that.

2. It will work quite fine until you will change your database/application structure; you will need to modify your friendship creation code everywhere. In case of using domain-specific method, you should usually end with just modifying your #add_friend/#add_to_friends_of code.

What do you think about these approaches?

Comments

Leave a response

  1. Francisco HernandezJuly 19, 2007 @ 06:33 PM

    I would probably use the 2nd method myself since theres no leakage of the underlying use of AR.

    Though, you could also consider something like: Friendship.create!(:friend => @user, :befriender => @friend)

    that seems to be more inline if you’re into the whole RESTful way of doing things..

  2. Luis LavenaJuly 19, 2007 @ 08:08 PM

    As Francisco said, I’ll go for a more RESTful plan for doing the relations.

    But (as always), Demeter’s law (only talk to your closes friends), the whole @@user.friendship.create(...)@ don’t feel right.

    Friendship.new(params[:friendship]) ... REST and API friendly ;-)

  3. SKJuly 19, 2007 @ 10:20 PM

    I would go for the DSL way if you are using the code to model some business logic involving people and friendships. If it is just the model behind a RESTful controller in a simple CRUD application I would stick with the RESTful way.