enum-help rails

Enum-help

Trong bài trước tôi đã nói cơ bản về việc sử dụng enum trong Rails. Trong bài viết này tôi sẽ nói chi tiết hơn về một kĩ thuật sử dụng enum với I18n

Ta lấy ví dụ đối với một model sử dụng enum với trường status như sau

class Order < ActiveRecord::Base
  enum status: { "nopayment" => 0, "finished" => 1, "failed" => 2 }
end

Khi đó trường status sẽ có các giá trị "nopayment" tương ứng với 0 trong cơ sở dữ liệu, tương tự với "finished", "failed".

Về phần giao diện người dùng, ví du với form chọn status ta có như sau:

<%= form.select :status, Order.statuses %>

Tuy nhiên chúng ta nên hiển thị giá trị status tương ứng với ngôn ngữ phù hợp chứ không nên hiển thị các giá trị ban đầu là "nopayment", "finished", ...

Có một cách đơn giản là ta có thể tự định nghĩa i18n theo cấu trúc nào đó có thể sử dụng được

Ví dụ:

ja:
  order:
    status:
      finished: 完成
      nopayment: 未支付
      failed: 失败

Tiếp theo ta viết một số method trong model Order để lấy giá trị i18n này

class << self
  def statuses_i18n
    statuses.each_with_object({}) do |(k, _), obj|
      obj[I18n.t("order.status.#{k}")] = k
    end
  end
end

def status_i18n
  I18n.t("order.status.#{status}")
end

Sau đó sửa lại trong view như sau form.html.erb

<%= form.select :status, Order.statuses_i18n %>

show.html.erb

<%= @order.status_i18n %>

index.html.erb

<td><%= order.status_i18n %></td>

Như vậy ta đã xong việc sử dụng i18n với một thuộc tính enum theo cách thủ công. Tuy nhiên chúng ta có thể dùng một thư viện "enum-help" hỗ trợ cho việc này, sử dụng rất đơn giản mà không phải mất công viết code.

Thêm gem 'enum_help' vào tron Gemfile Chạy bundle install

Ta đã thêm được enum_help vào trong project, việc tiếp theo ta sẽ sử dụng enum_help với thuộc tính status Với việc hỗ trợ của enum_help ta sẽ không phải viết method statuses_i18nstatus_i18n. Enum-help sẽ tự động thêm các method này cho thuộc tính enum thuộc kiểu enum

Tiếp theo ta config lại i18n theo đúng chuẩn của enum help

ja:
  enums:
    order:
      status:
        finished: 完成
        nopayment: 未支付
        failed: 失败

Done! Bạn có thể thấy sau khi thêm gem enum-help ta hoàn toàn loại bỏ được việc viết thủ công các method để lấy giá trị i18n của các thuộc tính enum. Như vậy việc sử dụng enum-help đối với các thuộc tính kiểu enum trong Rails giúp ta giảm được khá nhiều công sức trong việc hiển thị i18n cho các thuộc tính enum.

Cảm ơn bạn đã theo dõi bài viêt!

Tham khảo

  1. Bạn có thể tham khảo code example ở đây Example
  2. Rails enum
  3. Enum-help

All Rights Reserved