Module: HasConstant::ClassMethods

Defined in:
lib/has_constant.rb

Overview

HasConstant takes a Proc containing an array of possible values for a field name The field name is inferred as the singular of the has constant name. For example has_constant :titles would use the database column “title”

USAGE:

class User < ActiveRecord::Base

include HasConstant
has_constant :titles, lambda { %w(Mr Mrs) }

end

User.titles #=> [‘Mr’, ‘Ms’]

@user.attributes #=> 0

@user.title_is?(‘Mr’) #=> true @user.title_is?(‘Ms’) #=> false

User.by_constant(‘title’, ‘Mr’) #=> [@user]

Instance Method Summary collapse

Instance Method Details

#has_constant(name, values = lambda { I18n.t(name) }, options = {}) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/has_constant.rb', line 41

def has_constant(name, values = lambda { I18n.t(name) }, options = {})
  singular = (options[:accessor] || name.to_s.singularize).to_s

  (class << self; self; end).instance_eval do
    define_method(name.to_s, values) if values.respond_to?(:call)
    define_method(name.to_s, lambda { values }) unless values.respond_to?(:call)
  end

  define_method(singular) do
    values[instance_variable_get("@#{singular}")]
  end

  # Add the setter method. This takes the string representation and converts it to an integer to store in the DB
  define_method("#{singular}=") do |val|
    if val.instance_of?(String)
      if values.index(val)
        instance_variable_set("@#{singular}", values.index(val))
      else
        raise ArgumentError,
          "value for #{singular} must be in #{self.class.send(name.to_s).join(', ')}"
      end
    else
      instance_variable_set("@#{singular}", val)
    end
  end

  define_method("#{singular}_is?") do |value|
    truth = send(singular) == value.to_s
    if !truth && I18n.locale.to_s != 'en'
      truth = I18n.with_locale(:en) { send(singular) == value.to_s }
    end
    truth
  end

  define_method("#{singular}_is_not?") do |value|
    !send("#{singular}_is?", value)
  end

  define_method("#{singular}_in?") do |value_list|
    truth = value_list.include? send(singular)
    if !truth && I18n.locale.to_s != 'en'
      truth = I18n.with_locale(:en) { value_list.include?(send(singular)) }
    end
    truth
  end

  define_method("#{singular}_not_in?") do |value_list|
    !send("#{singular}_in?", value_list)
  end
end