Module: EnumFor::SingletonMethods
- Defined in:
- lib/values_for.rb
Instance Method Summary collapse
-
#values_for(*args) ⇒ Object
Creates an enumerable attribute on an ActiveRecord model.
Instance Method Details
#values_for(*args) ⇒ Object
Creates an enumerable attribute on an ActiveRecord model. Usage is as follows:
values_for :state, :has => [ :new, :composed, :served, :eaten ]
Any additional options will be passed directly to the ActiveRecord method :validates_inclusion_of, which is used to validate the assigned values to this attribute. Requires a column of type VARCHAR with the name of the first argument to values_for
.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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 |
# File 'lib/values_for.rb', line 18 def values_for(*args) opts = args. attribute = args.first attribute_s = attribute.to_s additives = Array.wrap(opts[:add]) plural_attribute = attribute_s.pluralize prefix = opts.has_key?(:prefix) ? opts[:prefix] : attribute_s # We don't accept the case where an empty string is a valid value, but we should provide a useful error message raise ArgumentError, "Can't use values_for with an empty string" if opts[:has].any?{|v| v.respond_to?(:empty?) && v.empty? } # Valid values are most likely Symbols anyway, but coerce them to be safe. valid_symbols = opts[:has].map{|v| v.to_sym } valid_symbols.each do |val_sym| val_s = val_sym.to_s prefixed_val = [ prefix, val_s ].compact.join('_') # Create +optional+ constants const_set(prefixed_val.upcase, val_sym) if additives.include?(:constants) # Create +optional+ named scopes named_scope prefixed_val, :conditions => { attribute => val_s } if additives.include?(:named_scopes) # Create +optional+ predicate methods, but don't overwrite existing methods if additives.include?(:predicate_methods) && !self.instance_methods.include?(prefixed_val) define_method(prefixed_val + '?') do # def foo? read_attribute(attribute) == val_s # read_attribute(:foo) == 'foo' end # end end end # Accepts assignment both from String and Symbol form of valid values. validates_inclusion_of attribute, opts.except(:has, :prefix, :add). merge(:in => valid_symbols | valid_symbols.map{|s| s.to_s } ) # Custom reader method presents attribute value in Symbol form. define_method(attribute_s) do # def foo unless self[attribute].nil? || self[attribute].empty? # unless self[:foo].nil? || self[:foo].empty? self[attribute].to_sym # self[:foo].to_sym unless self[:foo].nil? end # end end # end # Custom setter method casting all attribute input to String, allows # assignment from Symbol form. define_method(attribute_s + '=') do |other| # def foo=(other) self[attribute] = other.nil? ? nil : other.to_s # self[foo] = other unless other.nil? end # end # Make collection of all valid attribute Symbols available to user # from plural name of attribute as class method. cattr_reader plural_attribute.to_sym class_variable_set(:"@@#{plural_attribute}", opts[:has]) end |