如何在class << self
上下文中动态分配范围?
class Partner < ActiveRecord::Base
STATUS = {
pending: 0, # 0 account has a pending billing request (but is not yet open)
active: 1, # 1 account has an active base subscription
suspended: 2, # 2 account has been suspended (e.g. after a base subscription decline)
expired: 3, # 3 base subscription has expired
incomplete: 4, # 4 partner application process incomplete
closed: 5, # 5 account has been permanently closed
cancelled: 6 # 6 account has been cancelled by user (but is still unexpired)
}
after_initialize :setup_status_enums
def status
STATUS.key(read_attribute(:status))
end
def status=(s)
write_attribute(:status, STATUS[s])
end
private
def setup_status_enums
class << self
STATUS.map do |key, val|
raise "Collision in enum values method #{key}" if respond_to?("#{key.to_s}?") or respond_to?("#{key.to_s}!") or respond_to?("#{key.to_s}")
define_method "#{key.to_s}?" do
send("status") == key
end
define_method "#{key.to_s}!" do
send("status=", val)
end
scope key.to_sym, lambda { where(:status => val) }
end
end
end
end
答案 0 :(得分:0)
这样的事情应该有效。您可以在类定义中直接遍历STATUS哈希。
class Partner < ActiveRecord::Base
STATUS = {
pending: 0, # 0 account has a pending billing request (but is not yet open)
active: 1, # 1 account has an active base subscription
suspended: 2, # 2 account has been suspended (e.g. after a base subscription decline)
expired: 3, # 3 base subscription has expired
incomplete: 4, # 4 partner application process incomplete
closed: 5, # 5 account has been permanently closed
cancelled: 6 # 6 account has been cancelled by user (but is still unexpired)
}
STATUS.each do |key, val|
define_method "#{key.to_s}?" do
status == key
end
define_method "#{key.to_s}!" do
status = val
end
scope key, lambda { where(status: val) }
end
...
end
答案 1 :(得分:0)
您似乎正在寻找状态机。
在Ruby中,查看state_machine或aasm宝石。然后,您可以根据state
列定义范围(或者您可以命名为status
。)
状态机还可以帮助您管理状态之间的转换,因此您只能在特定的转换或状态上运行回调或验证。