也许scope
个就是你想要的.挑你喜欢的:
class Model < ApplicationRecord
enum :priority, {low: 10, moderate: 20, high: 30, very_high: 40}
##
# Add scopes, aka class methods. Append `.order(:priority)` if you like
#
# Model.min_priority(:high).pluck(:priority)
# #=> ["high", "high", "very_high"]
#
scope :min_priority, ->(name) { where("priority >= ?", priorities[name]) }
scope :max_priority, ->(name) { where("priority <= ?", priorities[name]) }
##
# Add a shortcut method
#
# Model.first.rank > Model.last.rank
# #=> false
#
def rank
priority_before_type_cast
end
##
# Define the methods you need
#
# Model.first.gt(Model.last)
# #=> false
#
def rank = priority_before_type_cast
def gt(other) = (rank > other.rank)
def gteq(other) = (rank >= other.rank)
def lt(other) = (rank < other.rank)
def lteq(other) = (rank <= other.rank)
##
# You could include Comparable into the model, which will give you:
# <, <=, >, >=, ==, between?, clamp
# However, `==` method will cause different models with the same priority
# to be equal each other. Other than that, you can compare your models:
#
# Model.first <= Model.last
# #=> true
#
alias_method :eq_copy, :== # copy the == method
include Comparable
alias_method :==, :eq_copy # put it back
remove_method :eq_copy # get rid of the witness
# this defines how your models compare to each other, aka spaceship operator
def <=> other
priority_before_type_cast <=> other.priority_before_type_cast
end
end
您可能不想将Comparable
包含在模型中,但仅定义<=>
也很有用,因为当您使用sort
时,您会比较:
>> Model.all.pluck(:priority)
=> ["low", "moderate", "high", "very_high", "low", "low"]
>> Model.all.sort.pluck(:priority)
=> ["low", "low", "low", "moderate", "high", "very_high"]
但sort_by
可以在没有额外服务的情况下解决这个问题,而且速度更快.(use 101 if applicable instead):
>> Model.all.sort_by(&:priority_before_type_cast) # or sort_by(&:rank)
=>
[#<Model:0x00007f99f1380b98 id: 1, priority: "low">,
#<Model:0x00007f99f06ad178 id: 5, priority: "low">,
#<Model:0x00007f99f06ad0d8 id: 6, priority: "low">,
#<Model:0x00007f99f06ad358 id: 2, priority: "moderate">,
#<Model:0x00007f99f06ad2b8 id: 3, priority: "high">,
#<Model:0x00007f99f06ad218 id: 4, priority: "very_high">]
还有一件事你可以做,以获得任意的顺序:
Model.in_order_of(:priority, [:low, :moderate, :high, :very_high])