Sử dụng enum trong ruby on rails
Bài đăng này đã không được cập nhật trong 10 năm
Enum là gì?
- Enum là kiểu dữ liệu liệt kê, giúp bạn tổ chức dữ liệu khoa học hơn, code được trong sáng dễ hiểu hơn.
- Khi khai báo một thuộc tính kiểu
enum, bạn có thể lưu dữ liệu vào database theo kiểuintegernhưng có thể truy vấn theo tên. Ví dụ:
class Conversation < ActiveRecord::Base
enum status: [:active, :archived]
end
# conversation.update! status: 0
conversation.active!
conversation.active? # => true
conversation.status # => "active"
# conversation.update! status: 1
conversation.archived!
conversation.archived? # => true
conversation.status # => "archived"
# conversation.status = 1
conversation.status = "archived"
conversation.status = nil
conversation.status.nil? # => true
conversation.status # => nil
Sử dụng enum như thế nào?
- Khai báo đơn giản. Ví dụ:
class Conversation < ActiveRecord::Base
enum status: [:active, :archived]
end
- Hỗ trợ các
scopedựa trên các giá trị. Ví dụ:
Conversation.active
Conversation.archived
Tất nhiên, bạn vẫn có thể truy vấn trực tiếp nếu scope không phù hợp với nhu cầu của bạn.
Conversation.where(status: [:active, :archived])
Conversation.where.not(status: :active)
- Bạn có thể đặt giá trị mặc định cho thuộc tính khi tạo database:
create_table :conversations do |t|
t.column :status, :integer, default: 0
end
Tốt nhất là đặt giá trị đầu tiên của thuộc tính làm giá trị mặc định.
- Cuối cùng, bạn cũng có thể đặt tên và giá trị của thuộc tính kiểu
enumtheo ý muốn một cách rõ ràng bằng cách sử dụng mộtHash. Ví dụ:
class Conversation < ActiveRecord::Base
enum status: {active: 0, archived: 1}
end
Lưu ý
- Khi sử dụng Array, các giá trị được lưu trữ trong database là thứ tự các giá trị xuất hiện trong mảng. Ví dụ,
:activesẽ được lưu là0vì nó là phần tử đầu tiên, và:archivedsẽ được lưu là1. Tổng quát, các phần tử thứisẽ được lưu lài-1trong database.
Vì vậy, khi một giá trị được thêm vào mảngenum, vị trí của nó trong mảng phải được duy trì cố định và các giá trị mới chỉ nên được thêm vào cuối mảng. Để loại bỏ các giá trị không cần thiết, nên sử dụng cú phápHashrõ ràng.
Trong một số trường hợp, có thể bạn cần phải lấy ra các giá trịintegertrong database. Các giá trị này sẽ được lấy ra thông qua mộtclass methodvới tên là số nhiều của thuộc tính, và trả về mảng giá trị trong mộtHashWithIndifferentAccess:
Conversation.statuses[:active] # => 0
Conversation.statuses["archived"] # => 1
Sử dụng class method này khi bạn cần biết giá trị thực sự của thuộc tính được lưu trong database. Ví dụ, bạn có thể sử dụng khi tạo một query SQL:
Conversation.where("status <> ?", Conversation.statuses[:archived])
- Bạn có thể sử dụng tùy chọn
:_prefixhoặc:_suffixkhi cần khai báo nhiềuenumvới các giá trị giống nhau. Nếu giá trị truyền vào là đúng, cácmethodcủaenumsẽ được thêm vào các tiền tố/hậu tố tương ứng. Ngoài ra, bạn cũng có thể cung cấp một giá trị khác cho:_prefix/:_suffix
class Conversation < ActiveRecord::Base
enum status: [:active, :archived], _suffix: true
enum comments_status: [:active, :inactive], _prefix: :comments
end
Với các ví dụ trên, bạn có thể sử dụng các method và scope với tiền tố và hậu tố như mong muốn:
conversation.active_status!
conversation.archived_status? # => false
conversation.comments_inactive!
conversation.comments_active? # => false
Thank you for reading!
All rights reserved