Instantly share code, notes, and snippets.

Embed
What would you like to do?
# lib/static_value.rb
class StaticValue < Stuct.new(:id, :name)
alias :to_s :name
end
# lib/static_list.rb
module StaticList
extended do |list|
def list.all
constants.map do |constant_name|
const_get(constant_name)
end
end
def list.form_options
all.map do |static_value|
[ static_value.name, static_value.id ]
end
end
def selected(static_value_id)
all.detect do |static_value|
static_value.id == static_value_id
end
end
def list.valid_ids
all.map(&:id)
end
end
end
# app/models/concerns/greeting.rb
module GreetingList
extend ActiveSupport::Concern
extend StaticList
HI = StaticValue.new(1, 'Hi')
HELLO = StaticValue.new(2, 'Hello')
DEAR = StaticValue.new(3, 'Dear')
OTHER = StaticValue.new(4, 'Other')
included do
validates :greeting_id, presence: true,
inclusion: { in: Greeting.valid_ids }
end
def greeting
GreetingList.selected(greeting_id)
end
end
# app/models/person.rb
class Person < ActiveRecord::Base
include GreetingList
end
@ravinggenius

This comment has been minimized.

Copy link
Owner

ravinggenius commented Apr 4, 2014

Refactor opportunities:

  • Instead of assigning StaticValues to constants, add a hook method to StaticList that collects the values: add_value StaticValue.new(1, 'Hi'). The refactor the generated methods to read from the hook instead of constants. I probably wouldn't do this if even on value needed to be special (GreetingList::OTHER).
  • Get fancy with method_missing to emulate more features from Rails' enum.
  • Memoize generated methods with instance variables.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment