12/08/2018, 14:11

Form Objects Pattern in Rails

Khi bạn có một form phức tạp, một form phải xử lý 2,3, thậm chí nhiều object một lúc. Bạn sẽ làm như thế nào? Đối với tôi, thì tôi thường hay sử dụng Form Objects. Vậy tại sao lại dùng Form Object, và dùng nó như thế nào? thì bài viết hôm nay tôi sẽ đề cập đến điều này Tại sao lại sử dụng Form ...

Khi bạn có một form phức tạp, một form phải xử lý 2,3, thậm chí nhiều object một lúc. Bạn sẽ làm như thế nào? Đối với tôi, thì tôi thường hay sử dụng Form Objects. Vậy tại sao lại dùng Form Object, và dùng nó như thế nào? thì bài viết hôm nay tôi sẽ đề cập đến điều này

Tại sao lại sử dụng Form Objects?

Bạn đã bao giờ nghe đến fat models? Fat models là gì? Nó muốn nói về vấn đề, một model của bạn phải thực hiện quá nhiều nhiệm vụ, cả việc authentication và accepting attributes cho các model khác, dẫn đến tình trạng nó quá lớn. Và khi đó, model sẽ vi phạm một quy tắc rất phổ biến đó là the single responsibility principle.

The single responsibility principle states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class.

Và đó là vấn đề của bài toán mà chúng ta đã đưa ra xử lý một form phức tạp. Và chúng ta giải quyết nó bằng Form Objects Pattern.

Tiếp theo, chúng ta sẽ cùng ứng Form objects trong một bài toán cụ thể.

Form Objects Pattern

1. Bài toán.

Chúng ta có một form để người dùng đăng kí sử dụng hệ thống của mình. Và ở trong đó, chúng ta yêu cầu người dùng nhập những thông tin cơ bản như: email, first_name, last_name, ngoài ra chúng ta còn yêu cầu người dùng nhập thông tin của company của họ như tên cty, địa chỉ. Đồng thời thông báo cho admin của hệ thống biết về thông tin của người dùng đã đăng kí. Rõ ràng ở đây, chúng ta cần xử lý lưu thông tin của 2 đối tượng cùng một lúc đó là: user và company, và thực hiện hành động gửi thông báo.

Chúng ta sẽ sử dụng Form objects pattern cho bài toán này.

2. Form objects.

Bước đầu tiên, chúng ta sẽ tạo một Object cho form register, như sau:

#app/forms/registration.rb
class Registration
  include ActiveModel::Model

  attr_accessor :company_name, :company_address, :email, :first_name, :last_name

  validates :company_name, presence: true
  validates :company_address, presence: true
  validates :email, presence: true, email: true
  validates :first_name, presence: true
  validates :last_name, presence: true

  def save
    if valid?
      # Do something
      # - create company
      # - create user
      # - send notifications
      true
    else
      false
    end
  end

  private
  def create_company
    # handle create a company
  end

  def create_user
    # handle create a company
  end

  def sent_notifications
    # sent notifications to admin
  end
end

Ở đây, chúng ta thực hiện validations cho các thuộc tính như bình thường. Đồng thời viết thêm method save tương tự như method save mặc định của ActiveRecord, để thực hiện những action mà chúng ta cần thực hiện như: tạo company, tạo user, gửi thông báo.

Tiếp theo, thật quen thuộc, chúng ta sẽ thực hiện những gì giống như một form bình thường của Rails.

Tạo controller và views tương ứng thôi nào.

# app/controllers/registration_controller.rb
class RegistrationsController < ApplicationController
  def new
    @registration = Registration.new
  end

  def create
    @registration = Registration.new registration_params
    if @registration.save
      # do something
    else
      render :new
    end
  end

  private

  def registration_params
    params.require(:registration).permit :company_name, :company_address,
      :email, :first_name, :last_name
  end
end
# app/views/registration/new.html.erb
<%= form_for @registration do |f| %>
  <%= f.label :company_name, t(".company_name") %>:
  <%= f.text_field :first_name %>
  ...
  <%= f.submit %>
<% end %>

Nhìn nó thật quen thuộc đúng ko             </div>
            
            <div class=

0