Delegate in rails
Bài đăng này đã không được cập nhật trong 6 năm
-
Giới thiệu
Delegration Design pattern là một kỹ thuật mà đối tượng cho thấy hành vi nhất định, nhưng nó thực sự chịu trách nhiệm thực hiện hành vi đó cho một đối tượng liên quan.
Thư viện chuẩn của Ruby chứa một module Delegate nhằm mục đích để cung cấp hỗ trợ cho các Delegation pattern.
-
Thực thi
Nếu dự án của bạn sử dụng ActiveSupport, bạn sẽ có một cách sạch sẽ hơn và dễ dàng để thực hiện delegation pattern: Module#Delegate. Nó cung cấp một module delegate, bạn có thể sử dụng trong các class của bạn hoặc trong các module của bạn để delegate một phương thức cho cụ thể một đối tượng liên kết.
Ví dụ: Ta có 2 class như sau:
class Post
belongs_to :user
end
class User
has_many :posts
end
Nếu bạn muốn gọi phương thức Post.name để trả về tên của user có bài post này, thường thì bạn sẽ phải tạo 1 hàm như sau:
class Post
belongs_to :user
def name
# let's use try to bypass nil-check
user.try(:name)
end
end
Nhưng với delegate, bạn chỉ cần làm như sau:
class Post
belongs_to :user
delegate :name, :to => :user, :allow_nil => true
end
Phương thức delegate có thể thực hiện trong mọi hoàn cảnh, nó không giới hạn ActiveRecord models
-
Các options
Phương thức delegate hiểu một số lựa chọn bổ sung, hữu ích để thực hiện hành vi.
Prefix có thể set là true để quy định tên phương thức của đối tượng delegate tới. Bạn cũng có thể custom prefix.
class Post
belongs_to :user
delegate :name, :to => :user, :prefix => true
# post.user_name
delegate :name, :to => :user, :prefix => "author"
# post.author_name
end
**allow_nil** là một option thực sự rất hay cho phép phương thức được gọi tới chấp nhận trường hợp nil. Bởi mặc định khi ta gọi tới phương thức của đối tượng liên quan mà bị nil, lập tức sẽ báo lỗi "**NoMethodError**".
Thay vì chúng ta phải if else cho trường hợp này thì delegate sẽ giúp chúng ta.
class Post
belongs_to :user
delegate :name, :to => :user, :prefix => true
end
Post.new.user_name
# raise NoMethodError
class Post
belongs_to :user
delegate :name, :to => :user, :prefix => true, :allow_nil => true
end
Post.new.user_name
# => nil
-
Kết
Đây là tất cả những gì mình hiểu về delegate mà mình muốn chia sẻ tới các bạn, hi vọng giúp ích được phần nào cho các bạn đang muốn tìm hiểu về delegate.
-
Tài liệu liên quan
https://simonecarletti.com/blog/2009/12/inside-ruby-on-rails-delegate/
All rights reserved