Computer >> Máy Tính >  >> Lập trình >> Ruby

Tạo các thuộc tính dễ đọc, dễ đọc với ActiveRecord Enums

Hãy tưởng tượng một câu hỏi có thể là “đang chờ xử lý”, “được chấp thuận” hoặc “bị gắn cờ”. Hoặc số điện thoại là “nhà riêng”, “văn phòng”, “di động” hoặc “fax” (nếu là năm 1982).

Một số mô hình yêu cầu loại dữ liệu này. Thuộc tính chỉ có thể có một trong một vài giá trị khác nhau. Và bộ giá trị đó hầu như không bao giờ thay đổi.

Đó là tình huống, nếu đó là Ruby đơn thuần, bạn chỉ cần sử dụng một biểu tượng.

Bạn có thể tạo mô hình PhoneNumberType hoặc QuestionStatus và belongs_to mối quan hệ để giữ những giá trị này, nhưng điều đó dường như không đáng. Bạn có thể nhét chúng vào một tệp yaml, nhưng bây giờ bạn phải tìm ở một nơi hoàn toàn khác để tìm ra những gì đối tượng của bạn có thể làm.

Trong 4.1, Rails đã cố gắng giải quyết vấn đề này với ActiveRecord enums.

Một vài giá trị trong mô hình

ActiveRecord enums khá dễ dàng. Bạn cung cấp cho mô hình của mình một integer cột:

bin/rails g model phone number:string phone_number_type:integer

Liệt kê các giá trị mà thuộc tính có thể nhận:

app / models / phone.rb
class Phone < ActiveRecord::Base
  enum phone_number_type: [:home, :office, :mobile, :fax]
end

Và bây giờ bạn có thể xử lý chuỗi thay vì số.

Thay vì điều này:

irb(main):001:0> Phone.first.phone_number_type
=> 3

Bạn sẽ thấy điều này:

irb(main):002:0> Phone.first.phone_number_type
=> "fax"

Bạn có thể thay đổi thuộc tính đó bằng cách sử dụng chuỗi hoặc int:

irb(main):003:0> phone.phone_number_type = 1; phone.phone_number_type
=> "office"
irb(main):004:0> phone.phone_number_type = "mobile"; phone.phone_number_type
=> "mobile"

Hoặc thậm chí sử dụng phương pháp bang:

irb(main):005:0> phone.office!
=> true
irb(main):006:0> phone.phone_number_type
=> "office"

Bạn nhận được các phương thức để hỏi xem thuộc tính của bạn có một số giá trị cụ thể hay không:

irb(main):007:0> phone.office?
=> true

Và bạn có thể tìm thấy tất cả các đối tượng có giá trị mà bạn đang tìm kiếm:

irb(main):008:0> Phone.office
  Phone Load (0.3ms)  SELECT "phones".* FROM "phones" WHERE "phones"."phone_number_type" = ?  [["phone_number_type", 1]]

Nếu bạn muốn xem tất cả các giá trị khác nhau mà bạn có thể sử dụng, cùng với các số được liên kết với chúng, hãy sử dụng phone_number_types phương thức lớp:

irb(main):009:0> Phone.phone_number_types
=> {"home"=>0, "office"=>1, "mobile"=>2, "fax"=>3}

Điều này làm cho chúng dễ dàng đưa vào một biểu mẫu HTML:

app / views / phone / _form.html.erb
<div class="field">
  <%= f.label :phone_number_type %><br>
  <%= f.select :phone_number_type, Phone.phone_number_types.keys %>
</div>

Tạo các thuộc tính dễ đọc, dễ đọc với ActiveRecord Enums

Một số nội dung cần theo dõi

Tuy nhiên, Enums không phải là không có vấn đề. Bạn phải ghi nhớ một số điều nếu không muốn gặp rắc rối sau này.

Khi bạn xác định một enum, thứ tự quan trọng. Vì vậy, nếu bạn quay lại mã của mình và quyết định rằng các giá trị đó thực sự phải theo thứ tự bảng chữ cái:

app / models / phone.rb
class Phone < ActiveRecord::Base
  enum phone_number_type: [:fax, :home, :mobile, :office]
end

Điện thoại của bạn sẽ không còn đúng loại nữa. Bạn có thể giải quyết vấn đề này bằng cách nói với enum số nào đi với giá trị nào:

app / models / phone.rb
class Phone < ActiveRecord::Base
  enum phone_number_type: {fax: 3, home: 0, mobile: 2, office: 1}
end

Nhưng thực sự, lựa chọn tốt nhất của bạn là giữ cho thứ tự nhất quán.

Một vấn đề lớn hơn là phải làm gì bên ngoài thế giới Rails. Mặc dù Rails coi các giá trị enum này là các chuỗi, chúng chỉ là các số bên trong cơ sở dữ liệu của bạn. Vì vậy, ai đó đang xem dữ liệu thô của bạn sẽ có không biết những con số đó có ý nghĩa gì. Điều này cũng có nghĩa là mọi ứng dụng đọc cơ sở dữ liệu đó sẽ phải biết ánh xạ enum đó.

Bạn có thể kết xuất ánh xạ enum của mình vào cơ sở dữ liệu hoặc tệp yaml nếu bạn thực sự cần người khác xem chúng. Nhưng đó không phải là KHÔ, bởi vì bây giờ bạn đang xác định enum của mình ở hai nơi. Và nếu bạn đang đi xa đến mức đó, có thể tốt hơn là bạn nên làm những gì chúng ta đã tránh ngay từ đầu:tạo một mô hình và liên kết hoàn toàn riêng biệt để Điện thoại sẽ belongs_to một PhoneNumberType.

Nhưng nếu bạn đang giữ cho nó đơn giản, enums là một cách tuyệt vời để bắt đầu.

Tái bút. Trong trường hợp bạn bỏ lỡ, hãy Practice Rails sẽ được bao gồm trong Gói sách Ruby, ra mắt vào Thứ Hai, ngày 6 tháng 7. Hãy mua nó và 5 cuốn sách Ruby tuyệt vời khác với mức chiết khấu cực lớn!