Tìm hiểu gem Draper trong rails
Bài đăng này đã không được cập nhật trong 8 năm
Draper là 1 gem bổ trợ để viết code trông sáng sủa hơn khi bạn viết code với decorator. Bạn hoàn toàn có thể lựa chọn sử dụng hay không sử dụng draper hay decorator trong project của mình nhưng tốt hơn hết là nên sử dụng để đưa project của mình về đúng với bản chất của ruby on rails ( hướng đối tượng, dễ đọc dễ hình dung).
Tại sao lại sử dụng decorator?
Tưởng tưởng ứng dụng của bạn có 1 model là Article. trong controller, bạn có method để show bài viết đại khái như sau:
app/controllers/articles_controller.rb
def show
@article = Article.find(params[:id]).decorate
end
ở trong lớp view, khi bạn muốn sử kiểm tra nếu bài viết này đã được publick thì sẽ in ra ngày tháng năm bài viết được create. còn nếu không thì in ra cụm từ unpublish. Một trong những cách hữu hiệu để xử lí vấn đề này là helper. Đúng, chính xác đó là những điều mình hay làm, đại khái nó sẽ như sau:
app/helpers/articles_helper.rb
def publication_status(article)
if article.published?
"Published at #{article.published_at.strftime('%A, %B %e')}"
else
"Unpublished"
end
end
Nhưng hãy tưởng tượng mà xem, viết 1 hàm trong helper để xử lí 1 tác vụ mà chỉ dùng cho model Article thì thật là không hay 1 chút nào. OK, hãy chuyển nó vào model. Mà khoan, chẳng phải như vậy sẽ vi phạm nguyên tắc fat model hay sao.
OK đó là tất cả những lí do mà tôi phải tìm bắt tay vào tìm hiểu gem draper. Bây giờ hãy xem chính xác những gì mà gem này có thể thực hiện. Chúng ta đi tiến hành cài đặt nó.
Cài đặt
Thêm "gem" vào Gemfile:
gem 'draper'
Viết Decorators
Decorators kế thừa từ Draper::Decorator, được đặt trong thư mục app/decorators và được đặt tên theo model mà nó bổ trợ. app/decorators/article_decorator.rb
class ArticleDecorator < Draper::Decorator
...
end
khi bạn đã cài đặt gem và có controller thì bạn sẽ có được 1 decorator với :
rails generate resource Article
nhưng nếu model Article đã tồn tại thì có thể dùng :
rails generate decorator Article
để create ArticleDecorator.
Truy cập Helpers
Tất cả các hàm trong rails helper đều có thể sử dụng trong decorator với object h để gọi ra các hàm trong helper. Nhưng nếu quá lười để viết thêm 1 đoạn 1 kí tự như vậy bạn hoàn toàn có thể add:
include Draper::LazyHelpers
vào trong class để có thể gọi helper như trong view.
Accessing the model
để truy cập vào model trong decorate bạn phải sử dụng từ khóa object. nó cũng tương tự như self vậy
class ArticleDecorator < Draper::Decorator
def published_at
object.published_at.strftime("%A, %B %e")
end
end
Sử dụng decorator với object
Sử dụng trong single object Nếu bạn khai báo
@article = Article.first.decorate
thì object @article sẽ trỏ đến decorator ArticleDecorator và có thể sử dụng thoải mái các method trong đó vì khi khai báo như vậy thì ArticleDecorator đã được inject vào object. Trong trường hợp bạn sử Decorator có tên khác hoặc bạn mướn inject 1 decorator hoàn toàn khác vào đối tượng, bạn có thể khai báo:
@widget = ProductDecorator.new(Widget.first)
#or, equivalently
@widget = ProductDecorator.decorate(Widget.first)
Collections
nếu bạn có 1 collection của object, bạn có thể inject decorator cho tất cả các object trong đó bằng 1 câu lệnh
@articles = ArticleDecorator.decorate_collection(Article.all)
hoặc
@articles = Article.popular.decorate
cho trường hợp tên model trùng tên decorator.
Chú ý: trong rails 3 .all methods không trả vê 1 query vì thế bạn không thể thực hiện decorate cho colection từ method này, rails 4 dùng bình thường.
Decorating Associated Objects
giả sử như model user có quan hệ với article mà article model lại cũng có decorate riêng của nó thì phải làm như thế nào? Đây là câu trả lời cho bạn:
class UserDecorator < Draper::Decorator
decorates_association :article
end
Kêt luận
Trên đây tôi đã giới thiệu sơ qua về gem draper. Có thể thấy nó là 1 gem khá hay. Nhưng trên quan điểm của từng người thì nó có ưu điểm và nhược điểm khác nhau. Nếu muốn tìm hiểu kĩ hơn thì có thể tham khảo các link sau.
https://github.com/drapergem/draper
http://thepugautomatic.com/2014/03/draper
http://tutorials.jumpstartlab.com/topics/decorators.html
Hãy cân nhắc nhắc kĩ trước khi dùng 1 gem nào đó. Cảm ơn các bạn đã ghé qua!!!
All rights reserved