12/08/2018, 15:18

Cells trong Ruby on rails

cells là gì Khi làm việc với view của Rails, không ngày nào mà không sử dụng tới method partial. Tuy nhiên, partial chỉ là 1 tính năng để gộp và tái sử dụng code view nhiều lần mà thôi. Khi muốn gộp chung cả logic vào để tạo ra template thì vấn đề sẽ rất phức tạp. Khi gặp vấn đề này, cells sẽ ...

cells là gì

Khi làm việc với view của Rails, không ngày nào mà không sử dụng tới method partial. Tuy nhiên, partial chỉ là 1 tính năng để gộp và tái sử dụng code view nhiều lần mà thôi. Khi muốn gộp chung cả logic vào để tạo ra template thì vấn đề sẽ rất phức tạp. Khi gặp vấn đề này, cells sẽ phát huy tối đa sức mạnh của mình. Cells là 1 gem được sử dụng để gộp cả view lẫn controller lại thành 1 package, với những view có logic phức tạp, thì cells sẽ giúp code trở nên dễ đọc và dễ dàng tái sử dụng hơn.

Những trường hợp dùng cells

  • Hiển thị popup login
  • Hiển thị ranking ở side menu ...

Ví dụ với popup login

Khi sử dụng partial, ta thường viết như sau :

  • unless user_signed_in? .header .headerlogin-button = link_to 'login', 'javascript:void(0);' = render partial: 'popup_login'

popup_login.html.haml

  • unless user_signed_in? .popup-login = form_for(@user, url:user_session_path) do |f| %dl %dt= f.label :email %dd= f.email_field :email %dt= f.label :password %dd= f.password_field :password = f.submit 'Login' :javascript ('.headerlogin-button a').click(function(){ ('.popup-login').css({ 'display' : 'block'}); }); Vấn đề của cách viết này là trong _popup_login.html.haml có sử dụng @user, và @user này được tạo ra ở đâu. Nếu trong controller không định nghĩa @user thì đoạn code trên chắc chắn bị lỗi. Có 2 cách giải quyết ở đây :
  • Định nghĩa @user ở trong tất cả các action có gọi popup_login.
  • Viết trong application controller

Các viết trong application_controller

Viết 1 cách đơn giản như sau : class ApplicationController < ActionController::Base before_action: :pre_load

def pre_load @user = User.new unless current_user.present? end end Lần này chỉ là popup_login, nên logic còn khá đơn giản. Nếu mọi thứ phức tạp hơn như ranking, comment, ... thì code chắc chắn sẽ không ngắn gọn và dễ hiểu như thế.

Viết bằng cells

dashboard.html.haml

= render_cell :popup_login, :show Login Cấu trúc thư mục của cells sẽ như sau :

/app /assets /cells /popup_login show.html.haml popup_login_cell.rb Các đoạn mã để thực hiện chức năng popup sẽ như sau : app/cells/popup_login_cell.rb class PopupLoginCell < Cell::Rails def show @user = User.new unless current_user.present? render end end app/cells/popup_login/show.html.haml

  • unless user_signed_in? .popup-login = form_for(@user, url:user_session_path) do |f| %dl %dt= f.label :email %dd= f.email_field :email %dt= f.label :password %dd= f.password_field :password = f.submit 'Login' :javascript ('.headerlogin-button a').click(function(){ ('.popup-login').css({ 'display' : 'block'}); });

Sử dụng cells

Thêm vào Gemfile

gem 'cells' cells được cung cấp thông qua generate :

rails generate cell popup_login show -e haml create app/cells/ create app/cells/popup_login create app/cells/popup_login_cell.rb create app/cells/popup_login/show.html.haml create test/cells/popup_login_cell.rb Khi gọi 1 package trong cells : = render_cell :popup_login, :show, :property => @property_name

0