sebastian.martinez

Rails delegate method 4

Posted by sebastian.martinez
on Thursday, June 04

Delegation is a feature Rails introduced in it’s 2.2 version, and in my opinion are quite useful and somehow something we don’t see too much around. The concept of delegation is to take some methods and send them off to another object to be processed.

Let me explain this with a brief example:

Suppose you have a User class for anyone registered on your site, and a Customer class for those who have actually placed orders:

class User < ActiveRecord::Base  
   belongs_to :customer  
end  

class Customer < ActiveRecord::Base  
   has_one :user  
end

As for now, if you are in a Customer instance, you can get their User information doing @customer.user.name, or @customer.user.email. Delegation allows you to simplify this:

class User < ActiveRecord::Base  
   belongs_to :customer  
end  

class Customer < ActiveRecord::Base  
   has_one :user  
   delegate :name, :name=, :email, :email=, :to => :user  
end

Now you can refer to @customer.name and @customer.email to retrieve and set values for those attributes directly. Pretty nice, huh?

We are now working on some code to make possible to inherit behaviour, along with polymorphic associations, so when you create a Cutomer, the User gets created as well with the data you provided when creating the customer, and so on.

So keep posted, for there will be more to come…

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

Comments

Leave a response

  1. wojtek wojtekOctober 29, 2009 @ 01:21 PM

    But,

    assume we’ve got:

    class Person < ActiveRecord::Base

    end

    class User < Person belongs_to :customer end

    class Customer < ActiveRecord::Base has_one :user delegate :name, :name=, :email, :email=, :to => :user end

    why it won’t work? (due to STI ????)

  2. Sebastián Martínez Sebastián MartínezNovember 04, 2009 @ 10:45 PM

    Wojtek, What you say works perfectly fine….what’s the error you’re getting?

  3. Stefan StefanNovember 13, 2009 @ 04:45 AM

    Customer.create(:name => ‘Foo Bar’, :last_purchase => ‘Book’)

    How can you have this create and associate the instance of User?

  4. Sebastián Martínez Sebastián MartínezNovember 26, 2009 @ 06:32 PM

    Stefan, I’m guessing you want to have a composite relation when whenever there is a Customer a User is associated to it. In this case one possible solution would be to override the ‘user’ method to return the associated user if there is any, or create one.

    Example:

    class Customer < ActiveRecord::Base
      has_one :user
      delegate :name, :name=, :email, :email=, :to => :user
    
      alias orig_user user
      def user
        orig_user || build_user
      end
    end

    Another better approach would be overriding ActiveRecord::Base initialize method in order to create the associated object before the delegated attributes are set.

Comment