Friday 6 April 2012

Delegate in Rails

It provides a delegate class method to easily expose contained objects’ methods as your own. 

It passes one or more methods (specified as symbols or strings) . 

And the name of the target object via the :to option(it can be a symbol or string).

Delegation is particularly useful with ActiveRecord associations:


class Parent < ActiveRecord::Base
  def welcome
    "Welcome all"
  end

  def thanku
    "Thank you all"
  end
end

class Child < ActiveRecord::Base
  belongs_to :parent
  delegate :welcome, :to => :parent
end 
 
Child.new.welcome   # => "Welcome all"
Child.new.thanku # => NoMethodError: undefined method `thanku' for #<Child:0x1af30c>
 

Multiple delegates to the same target are allowed: 

 
class Child < ActiveRecord::Base
  belongs_to :Parent
  delegate :welcome, :thanku, :to => :parent
end

Child.new.thanku # => "Thank you all" 
 

Methods can be delegated to instance variables, class variables, or constants by providing them as a symbols:

 
class Child
  CONSTANT_ARRAY = [0,1,2,3]
  @@class_array  = [4,5,6,7]

  def initialize
    @instance_array = [8,9,10,11]
  end
  delegate :sum, :to => :CONSTANT_ARRAY
  delegate :min, :to => :@@class_array
  delegate :max, :to => :@instance_array
end 
 
Child.new.sum # => 6
Child.new.min # => 4
Child.new.max # => 11 

Delegates can optionally be prefixed using the :prefix option. If the value is true, the delegate methods are prefixed with the name of the object being delegated to.

 
Customer = Struct.new(:name, :address)

class Invoice < Struct.new(:buyer)
  delegate :name, :address, :to => :buyer, :prefix => true
end

customer = Customer.new("Debadatta Pradhan", "Bhubaneswar")
invoice = Invoice.new(customer)
invoice.buyer_name    # => "Debadatta Pradhan"
invoice.buyer_address # => "Bhubaneswar"

No comments:

Post a Comment