Sử dụng enum trong ruby on rails
Bài đăng này đã không được cập nhật trong 9 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ểuinteger
như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
scope
dự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
enum
theo ý 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ụ,
:active
sẽ được lưu là0
vì nó là phần tử đầu tiên, và:archived
sẽ được lưu là1
. Tổng quát, các phần tử thứi
sẽ được lưu lài-1
trong 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ápHash
rõ 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ịinteger
trong database. Các giá trị này sẽ được lấy ra thông qua mộtclass method
vớ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
:_prefix
hoặc:_suffix
khi cần khai báo nhiềuenum
với các giá trị giống nhau. Nếu giá trị truyền vào là đúng, cácmethod
củaenum
sẽ đượ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