Last active
March 18, 2021 20:52
-
-
Save crawler/b7a92745500430e37535c34c7290f34f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module ActiveRecord | |
module EnumHelpers | |
extend ActiveSupport::Concern | |
module ClassMethods | |
def enum_helpers(name) | |
module_eval <<-RUBY, __FILE__, __LINE__ + 1 | |
# e.g. order.state_exactly? 'payment' | |
def #{name}_exactly? desired | |
unless self.class.#{name}s.keys.include?(desired.to_s) | |
raise( | |
ArgumentError, | |
"Invalid desired \\"\#\{desired\}\\" argument passed to " \ | |
"\#\{Array.wrap(caller)[0]\} one of \#\{self.class.#{name}s.keys.inspect\} expected" | |
) | |
end | |
#{name} == desired.to_s | |
end | |
# e.g. order.state_to? 'payment' | |
def #{name}_to? desired | |
self.class.#{name}s_to(desired).include?(#{name}.to_s) | |
end | |
# e.g. order.state_from? 'played' | |
def #{name}_from? desired | |
self.class.#{name}s_from(desired).include?(#{name}.to_s) | |
end | |
# Backward compatibility with order | |
# e.g. order.states_include? 'played' | |
alias :#{name}_include? :#{name}_from? | |
class << self | |
# e.g. Order.states_to 'payment' | |
def #{name}s_to desired, exclusive: false | |
values = #{name}s.values | |
values[0 .. (get_#{name}_index(desired.to_s) - (exclusive ? 1 : 0))] | |
end | |
# e.g. Order.states_from 'paid' | |
def #{name}s_from desired, exclusive: false | |
values = #{name}s.values | |
#{name}s.values[(get_#{name}_index(desired.to_s) + (exclusive ? 1 : 0)) .. -1] | |
end | |
# Backward compatibility with order | |
alias :#{name}_names_to :#{name}s_to | |
alias :#{name}_names_from :#{name}s_from | |
def get_#{name}_index(desired) | |
index = #{name}s.keys.index(desired.to_s) | |
if index.nil? | |
raise_invalid_desired_#{name}(desired) | |
end | |
index | |
end | |
# e.g. scope Order.state_from('placed') | |
def #{name}_from desired, exclusive: false | |
where(#{name}: #{name}s_from(desired, exclusive: false)) | |
end | |
# e.g. scope Order.state_to('placed') | |
def #{name}_to desired, exclusive: false | |
where(#{name}: #{name}s_to(desired, exclusive: exclusive)) | |
end | |
# e.g. scope Order.state('placed') | |
def #{name} desired, exclusive: false | |
unless #{name}s.keys.include?(desired.to_s) | |
raise_invalid_desired_#{name}(desired) | |
end | |
where(#{name}: desired) | |
end | |
protected | |
def raise_invalid_desired_#{name}(desired) | |
raise( | |
ArgumentError, | |
"Invalid desired \\"\#\{desired\}\\" argument passed to " \ | |
"\#\{Array.wrap(caller)[0]\} one of \#\{#{name}s.keys.inspect\} expected" | |
) | |
end | |
end | |
RUBY | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment