Những lỗi cơ bản thường gặp với lập trình viên Rails (Phần I)
Bài đăng này đã không được cập nhật trong 7 năm
Rails là một framework mã nguồn mở được sử dụng rộng rãi trên thế giới, được xây dựng dựa trên ngôn ngữ lập trình Ruby với tiêu chí làm đơn giản hóa quá trình phát triển ứng dụng web. Rails rất dễ sử dụng, nhưng cũng dễ mắc lỗi. Trong bài viết này, mình sẽ chỉ ra 10 vấn đề thương gặp khi làm việc với Rails, bao gồm cách tránh chúng và các vấn đề mà chúng gây ra.
1. Đưa quá nhiều logic vào trong controller:
Đối với những ai làm việc với Rails 1 thời gian chắc hẳn không còn lạ lẫm gì với hệ thống MVC của rails và câu "fat model, skinny controller". Tuy nhiên có khá nhiều bạn lập trình viên Rails vi phạm nguyên tắc này do việc chuyển những logic từ view (đáng ra được đặt ở helper) hoặc domain/model logic vào controller khá là dễ dàng. Việc dùng quá nhiều logic trong controller khiến cho việc chỉnh sửa code trong tương lai sẽ rất khó khăn và dễ gây ra những lỗi logic. Nói chung, chỉ những những hàm, code logic sau là nên có mặt trong controller của bạn:
- Kiểm soát session and cookie: Nó cũng có thể bao gồm các logic về authentication/authorization hoặc bất kỳ quá trình xử lý cookie bổ sung nào bạn cần thực hiện.
- Lựa chọn Model: Logic cho việc tìm kiếm các model đúng với các params được truyền vào từ các yêu cầu (request). Lý tưởng nhất là nên gọi một method đặt một instance variable dụ sẽ được sử dụng sau để trả về.
- Quản lý các params của yêu cầu: Tổng hợp các params và gọi ra một model method thích hợp để xử lý chúng.
- Rendering/redirecting: Hiển thị kết quả (html, xml, json, v.v.) hoặc chuyển hướng, nếu cần.
2. Đưa quá nhiều logic vào Views:
Hệ thống templating ERB của Rails là một cách tuyệt vời để xây dựng nên các trang với các biến content. Tuy nhiên nếu không cẩn thận, thành quả mà bạn thu được sẽ là 1 file rất lớn với sự pha trộn hỗn độn của code Html và code Ruby khiến cho việc sửa đổi và duy trì trở nên vô cùng khó khăn. Việc làm dụng code logic trong Views cũng sẽ dẫn đến lỗi lắp đi lặp lại code nhiều lần mà điều này là vi phạm nguyên tắc DRY (don't repeat yourself). Lỗi này có thể nhận ra qua một số cách. Một là sử dụng quá nhiều logic điều kiện trong Views, ví dụ như chúng ta có một phương thức current_user trả về người dùng hiện tại của trang web. Thông thường chúng ta sẽ dễ lặp lại đoạn code sau trong nhiều file Views khác nhau:
<h3>
Welcome,
<% if current_user %>
<%= current_user.name %>
<% else %>
Guest
<% end %>
</h3>
Có một cách tốt hơn để xử lý đó là đảm bảo giá trị name luôn được trả về dù người dùng có đăng nhập hay không. Để làm thế, chúng ta có thể định nghĩa 1 hàm current_user helper trong application_Controller:
require 'ostruct'
helper_method :current_user
def current_user
@current_user ||= User.find session[:user_id] if session[:user_id]
if @current_user
@current_user
else
OpenStruct.new(name: 'Guest')
end
end
Hàm này sẽ cho phép bạn thay thế đoạn code trên kia với 1 dòng lệnh đơn giản như sau:
<h3>Welcome, <%= current_user.name -%></h3>
Có một vài gợi ý để tránh phạm phải lỗi này đó là:
- Sử dụng Views layout và partical thích hợp để đóng gói lại những đoạn code thường sử dụng trên Views của bạn.
- Sử dụng presenters/decorators để đóng gói các logic khi xây dựng Views của Ruby. Sau đó bạn có thể thêm các hàm để thực hiện các logic này 1 cách hợp lý.
3. Đưa quá nhiều logic vào Model:
Hẳn bạn đang thắc mắc với 2 lỗi thường gặp trên, thì nơi thích hợp nhất để nhét một đống code logic hẳn phải là phần còn lại - Model. Điều này không hoàn toàn đúng, rất nhiều lập trình viên Rails đã phạm phải sai lầm này khi cố găng tống khứ hết đống code logic vào ActiveRecord model khiến cho nó trở thành một cơn ác mộng cho việc duy trì và phát triển model nói riêng hay ứng dụng web nói chung. Các chức năng như tạo ra các thông báo email, liên kết tới các dịch vụ bên ngoài, chuyển đổi sang các định dạng dữ liệu khác và những chức năng không có nhiều liên quan đến trách nhiệm chính của Model cần phải được ưu tiên ít hơn là việc tìm kiếm và duy trì dữ liệu trong cơ sở dữ liệu. Vậy nếu không được ở trong controller, không được dừng chân tại Views cũng không thể tá túc ở Model thì code logic nên đi đâu? Câu trả lời là POROs* (plain old Ruby objects) . Với một framework toàn diện như Rails, những lập trình viên mới thường sẽ lưỡng lự khi phải tạo những class của riêng họ mà không thuộc khuôn khổ của framework. Tuy nhiên, việc đưa logic ra khỏi model và chuyển tới POROs thường được khuyến nghị để tránh việc Models trở nên quá phức tạp. Với Poros, bạn có thể đóng gói những thứ như thông báo email hoặc tương tác API vào các class riêng chứ không phải ghép chúng thành một mô hình ActiveRecord. Với những suy nghĩ như trên thì chỉ những code logic sau đây nên tồn tại trong Models của bạn:
- ActiveRecord configuration: Ví dụ như các mối quan hệ hay các điều kiện cho dữ liệu (validate).
- Những hàm biến đổi đơn giản: Để đóng gói/cập nhật một số ít các thuộc tính và lưu trữ chúng trong cơ sở dữ liệu.
- Truy vấn phức tạp: Nói chung, bạn không nên sử dụng phương pháp where, hoặc bất kỳ phương pháp xây dựng truy vấn nào khác tương tự, bên ngoài Model class của chính nó.
Bài viết của mình tạm thời dưng lại tại đây, hẹn gặp lại các bạn trong các phần tiếp theo ( * ) Các bạn có thể tham khảo thêm về POROs tại đây Nguồn: https://www.toptal.com/ruby-on-rails/top-10-mistakes-that-rails-programmers-make
All rights reserved