Decorator in Rails
Khái niệm Decorator Như chúng ta đã biết, hệ thống RoR được xây dựng dựa trên mô hình MVC, trong đó: Model có vai trò xử lí logic và dữ liệu View nhận trách nhiệm hiển thị dữ liệu Controller là nơi trung gian điều phối dữ liệu, cầu nối giữa model và view Theo lí thuyết, model thường là nơi ...
Khái niệm Decorator
Như chúng ta đã biết, hệ thống RoR được xây dựng dựa trên mô hình MVC, trong đó:
- Model có vai trò xử lí logic và dữ liệu
- View nhận trách nhiệm hiển thị dữ liệu
- Controller là nơi trung gian điều phối dữ liệu, cầu nối giữa model và view Theo lí thuyết, model thường là nơi mà chúng ta tập trung những phương thức, hàm xử lí logic phức tạp. Tuy nhiên điều đó chỉ áp dụng được với những hệ thống nhỏ, còn với những dự án lớn, đòi hỏi nhiều công đoạn xử lý cầu kì, thì model không còn là nơi thích hợp nữa, nếu ta cứ cố chấp nhồi nhét quá nhiều hàm logic vào nó, thì model sẽ ngày một cồng kềnh hơn, và cũng vô cùng vất vả cho công đoạn maintain về sau. Để khắc phục vấn đề này, Rails có thêm các công cụ hỗ trợ rất mạnh mẽ, và 1 trong số đó chính là Decorator Decorator bản thân nó cũng là một pattern, có vai trò là cầu nối giữa model và view. Nó như là một lớp con trung gian, cho phép chúng ta tạo thêm các phương thức xử lý cho đối tượng mà không gây ảnh hưởng đến đối tượng khác trong cùng một lớp.
Implement
Có nhiều cách để chúng ta implement Decorator trong project của mình. Có thể thêm bằng cách thủ công, hoặc sử dụng một số gem như ActiveDecorator, Draper. Chúng ta sẽ thử implement bằng tay trước. Giả sử như chúng ta có bài toán về xây dựng ứng dụng quản lí thông tin người dùng chẳng hạn, bao gồm first_name, last_name, email.. và cần hiển thị trên browser first_name và last_name của user đó. Trường hợp này chúng ta sẽ cần dùng đến Decorator với cái tên UserDecorator. Trước tiên, xây dựng hệ thống quản lí User cơ bản bằng scaffold:
rails g scaffold User first_name:string last_name:string email:string
Sau đó tạo thêm folder decorators với đường dẫn app/decorators Chúng ta tiếp tục tạo UserDecorator trong decorators, sau đó định nghĩa một method xử lí việc lấy thông tin first_name, last_name của user:
module UserDecorator def full_name if first_name.blank? && last_name.blank? "Got nothing to show" else "#{first_name} #{last_name}" end end end
Để các đối tượng của lớp User có thể dùng được method full_name của UserDecorator, chúng ta chỉ cần include nó vào trong class User là ổn:
class User < ActiveRecord::Base include UserDecorator ... end
Rồi, giờ thì phía trên view chúng ta chỉ cần gọi method full_name ra cho bất kì instance variable nào của User thôi:
<p> <strong>Full name:</strong> <%= @user.full_name %> </p>
Ok, đó là cách mà chúng ta có thể implement Decorator bằng tay, tiếp đến sẽ là cách để sử dụng nó thông qua gem Draper: Bước thứ nhất là thêm gem file rồi bundle:
gem "draper"
Sau đó chúng ta khởi tạo UserDecorator:
rails generate decorator UserDecorator
Chúng ta được file user_decorator.rb như sau:
class UserDecorator < Draper::Decorator delegate_all end
Rồi sau đó chúng ta có thể tùy ý "decorate" các method bên trong nó thôi, tương tự như trong cách đầu tiên nhé. Sau khi "decorate" xong, chúng ta chỉ cần gọi kiểu .decorate với mọi đối tượng ActiveRecord nào trong project:
@user.decorate.full_name User.first.decorate.full_name
Vậy là xong, có thể thấy Draper cũng khá dễ hiểu và dễ sử dụng. Ngoài ra Draper cũng cung cấp khá nhiều method khác linh hoạt và mạnh mẽ, hỗ trợ cho chúng ta.
Tham khảo
Trên đây là một vài chia sẻ của mình về Decorator trong Rails, cảm ơn các bạn đã dành thời gian đọc bài viết. Các bạn cũng có thể tìm hiểu thêm tại: https://github.com/amatsuda/active_decorator https://github.com/drapergem/draper https://gorails.com/episodes/decorators-with-draper