Skip to content

Instantly share code, notes, and snippets.

@crawler
Last active March 18, 2021 20:52
Show Gist options
  • Save crawler/b7a92745500430e37535c34c7290f34f to your computer and use it in GitHub Desktop.
Save crawler/b7a92745500430e37535c34c7290f34f to your computer and use it in GitHub Desktop.
# 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