Delegate in rails

1.Giới Thiệu

Delegate giúp dễ dàng gọi các public methods của object khác giống như là của chính mình , Đặc biệt với các models có quan hệ phức tạp thì bạn có thể thực hiện gọi từ một class đến nhiều class khác.

Delegate rất hữu ích với Active Record associations

2.Bài toán

Ví dụ ta có bảng User có image, link_fb và một bảng User_infor chứa : name, email .

class User < ActiveRecord::Base
has_one :userinfor
end
class Userinfo < ActiveRecord::Base
belongs_to :user
end

Bình thường ta lấy thuộc tính name của user thì dùng :

user.userinfor.name

Nhưng với delegate ta có thể lấy bằng cách :

delegate :name, to: :userinfor

Nếu muốn lấy nhiều thuộc tính của user

delegate :name, :email, to: :userinfo

3.Delegate options

a. :to

Object mà bạn muốn sư dụng để gọi các public methods

delegate :name, :email, to: :userinfo

b. :prefix

Prefix có thể set là true để quy định tên phương thức của đối tượng delegate tới.

delegate :name, :email, to: :userinfo, prefix: :true

Lúc này các method tạo ra có tên là : userinfo_name, userinfor_email

Bạn cũng có thể customprefix :

delegate :name, :email, to: :userinfo, prefix: :user

Lúc này các method tạo ra có tên là : user_name, user_email

c. :allow_nil

Trả về nil thay vì lỗi NoMethodError khi target của method được delegatenil

delegate :name, :email, to: :userinfo, prefix: :user, allow_nil: true

4.Delegate có thể được sử dụng trong nhiều trường hợp Nó không giới hạn trong ActiveRecord :

Một Method có thể được gọi delegate với biến instance, biến class, hoặc hằng số.

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

Foo.new.sum # => 6
Foo.new.min # => 4
Foo.new.max # => 11

Có thể gọi delegate1 method của class bằng cách sử dụng :class

class Foo
  def self.hello
    "world"
  end

  delegate :hello, to: :class
end

Foo.new.hello # => "world"

Link tham khảo :

http://api.rubyonrails.org/classes/Module.html#method-i-delegate