Module: EasyAttributes::ClassMethods
- Defined in:
- lib/easy_attributes.rb
Overview
EasyAttributes::ClassMethods - Module defining methods added to classes when included
Examples
class MyClass
include EasyAttributes
attr_values :attr, name:value, ...
attr_enum :attr, :name, ....
attr_define :attr, :attr=>:defined_attr
attr_bytes :attr, ..., :base=>2
attr_money :attr, :precision=>2
attr_fixed :attr, :precision=>2
Instance Method Summary collapse
-
#attr_allowed(attribute, *args) ⇒ Object
Public: Defines an attribute as a set of values.
-
#attr_bytes(*args) ⇒ Object
Public: Adds byte attributes helpers to the class attr_bytes allows manipultion and display as kb, mb, gb, tb, pb Adds method: attribute_bytes=() and attribute_bytes(:unit, :option=>value ).
-
#attr_define(attribute, *definition) ⇒ Object
Public: Sets global definitions into the class by attribute name or Hash mapping.
- #attr_dollars(*args) ⇒ Object
-
#attr_enum(attribute, *args) ⇒ Object
Public: Defines an attribute as an Enumeration of symbol name.
-
#attr_fixed(*args) ⇒ Object
Public: Adds methods to get and set a fixed-point value stored as an integer.
-
#attr_money(*args) ⇒ Object
Public: Alias of attr_fixed for a money type with suffix of ‘money’ and precision of 2.
-
#attr_shared(*attributes) ⇒ Object
Public: Imports previously defined definitions into the class by attribute name or Hash mapping.
-
#attr_values(attribute, *args) ⇒ Object
Public: Defines an attribute with a Hash of symbolic synonyms for the values.
-
#define_easy_attribute_definition ⇒ Object
Adds once to class: Returns the EasyAttribute::Definition of the passed.
-
#easy_attribute_accessors(attribute, defn) ⇒ Object
Private: Creates attribute accessors for the attribute /definition for attr_values.
- #install_shared_attribute(name, shared_name = nil) ⇒ Object
Instance Method Details
#attr_allowed(attribute, *args) ⇒ Object
Public: Defines an attribute as a set of values. For String-type attributes
attribute - symbolic name of the attribute args - a list of allowed string names (symbols can be used for convenience as well)
Examples
attr_allowed :type, "mammal", :bird, :insect
Creates the same methods as attr_values().
Returns nothing
756 757 758 759 760 761 762 |
# File 'lib/easy_attributes.rb', line 756 def attr_allowed(attribute, *args) opt = args.last.is_a?(Hash) ? args.pop : {} vals = {} args.flatten.map { |v| vals[v.to_sym] = v.to_s } defn = Definition.new(attribute, vals, opt) easy_attribute_accessors(attribute, defn) end |
#attr_bytes(*args) ⇒ Object
Public: Adds byte attributes helpers to the class attr_bytes allows manipultion and display as kb, mb, gb, tb, pb Adds method: attribute_bytes=() and attribute_bytes(:unit, :option=>value )
attribites - List of attribute names to generate helpers for options - Hash of byte helper options
Example
attr_bytes :bandwidth
attr_bytes :storage, :kb_size=>1000, :precision=>2
Adds the following helpers
bandwidth_bytes() # => "10 GB"
bandwidth_bytes=("10 GB") # => 10_000_000_000
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 |
# File 'lib/easy_attributes.rb', line 925 def attr_bytes(*args) define_easy_attribute_definition @easy_attribute_definitions ||= {} opt = args.last.is_a?(Hash) ? args.op : {} args.each do |attribute| attribute = attribute.to_sym unless EasyAttributes::Config.orm == :active_model || opt[:orm] == :active_model attr_accessor attribute if EasyAttributes::Config.orm == :attr end #defn = Definition.find_or_create(attribute, {}, opt) defn = Definition.new(attribute, {}, opt) @easy_attribute_definitions[attribute] = defn # <attribute>_bytes() # Returns the symbolic name of the current value of "attribute" define_method("#{attribute}_bytes") do |*| self.class.easy_attribute_definition(attribute).format_bytes(self.send(attribute), *) end # <attribute>_bytes=(new_symbol) # Sets the value of "attribute" to the associated value of the passed symbolic name define_method("#{attribute}_bytes=") do |sym| self.send("#{attribute}=", self.class.easy_attribute_definition(attribute).parse_bytes(sym)) end end end |
#attr_define(attribute, *definition) ⇒ Object
Public: Sets global definitions into the class by attribute name or Hash mapping.
attributes - List of attributes to import from Config definitions mappings - Hash of atttribute names to a matching alternate name in the Config definitions
Examples (call like attr_values or attr_enum)
attr_define :status, :signup, :confirm, :unreachable, :delete
attr_define :status, signup:1, confirm:2, uncreachable:3, delete:4
Stores the definition in a symbol table for later attr_shared lookup
775 776 777 |
# File 'lib/easy_attributes.rb', line 775 def attr_define(attribute, *definition) find_or_create(attribute, *definition) end |
#attr_dollars(*args) ⇒ Object
1038 1039 1040 1041 |
# File 'lib/easy_attributes.rb', line 1038 def attr_dollars(*args) opt = args.last.is_a?(Hash) ? args.pop : {} attr_money(*args, opt.merge(method_suffix:'dollars')) end |
#attr_enum(attribute, *args) ⇒ Object
Public: Defines an attribute as an Enumeration of symbol name.
By default, the first symbol is mapped to 0 (zero), and increments by 1. The :start and :step values in the options hash can change those settings. Also, “#next()” is called on the start value, so any non-numeric object that supports that call can be used (such as a string). A nil in a position will skip that value, and any other non-symbol will reset the value of the next symbol to that one.
This is an alternate syntax for the attr_values() method
attribute - symbolic name of the attribute args - a list of symbol names, nil skip tokens, and value changes
* A symbol name will map to the current value
* A nil skips the current value in the list
* Any other value replaces the current value for the subsequent symbol
options - a optional key of :options=>name:value defines any options for the attribute
Examples
attr_enum :status, :active, :inactive # => {active:0, inactive:1}
attr_enum :month, :jan, :feb, ..., :dec, start:1 # => {jan:1, feb:2, ..., dec:12}
attr_enum :status, :active, :inactive, nil, :suspended, 99, :deleted, start:10, step:10
# => same as: {active:10, inactive:20, suspended:40, deleted:99}
Creates the same methods as attr_values().
Returns nothing
738 739 740 741 742 |
# File 'lib/easy_attributes.rb', line 738 def attr_enum(attribute, *args) opt = args.last.is_a?(Hash) ? args.pop : {} defn = Definition.new(attribute, args, opt) easy_attribute_accessors(attribute, defn) end |
#attr_fixed(*args) ⇒ Object
Public: Adds methods to get and set a fixed-point value stored as an integer.
attributes - list of attribute names to define options - Optional hash of definitions for the given list of attributes
:method_suffix - Use this as the alternative name to the *_fixed method names
:units - Use this as an alternative suffix name to the money methods ('dollars' gives 'xx_dollars')
:precision - The number of digits implied after the decimal, default is 2
:separator - The character to use after the integer part, default is '.'
:delimiter - The character to use between every 3 digits of the integer part, default none
:positive - The sprintf format to use for positive numbers, default is based on precision
:negative - The sprintf format to use for negative numbers, default is same as :positive
:zero - The sprintf format to use for zero, default is same as :positive
:nil - The sprintf format to use for nil values, default none
:unit - Prepend this to the front of the money value, say '$', default none
:blank - Return this value when the money string is empty or has no digits on assignment
:negative_regex - A Regular Expression used to determine if a number is negative (and without a - sign)
Examples:
attr_fixed :gpa, precision:1
attr_fixed :price, precision:2
Adds the following helpers
gpa_fixed() #=> "3.8"
gpa_fixed=("3.8") #=> 38
gpa_float() #=> 3.8
Returns nothing
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 |
# File 'lib/easy_attributes.rb', line 981 def attr_fixed(*args) define_easy_attribute_definition @easy_attribute_definitions ||= {} opt = args.last.is_a?(Hash) ? args.pop : {} suffix = opt.fetch(:method_suffix) { 'fixed' } args.each do |attribute| attribute = attribute.to_sym unless EasyAttributes::Config.orm == :active_model || opt[:orm] == :active_model attr_accessor attribute if EasyAttributes::Config.orm == :attr end defn = Definition.new(attribute, {}, opt) @easy_attribute_definitions[attribute] = defn # <attribute>_fixed() # Returns the symbolic name of the current value of "attribute" define_method("#{attribute}_#{suffix}") do FixedPoint::integer_to_fixed_point(send(attribute), self.class.easy_attribute_definition(attribute).) end # <attribute>_fixed=(new_value) # Sets the value of "attribute" to the associated value of the passed symbolic name define_method("#{attribute}_#{suffix}=") do |val| self.send("#{attribute}=", FixedPoint::fixed_point_to_integer(val, self.class.easy_attribute_definition(attribute).)) end # <attribute>_float() # Returns the value of the attribite as a float with desired precision point define_method("#{attribute}_float") do FixedPoint::integer_to_float(send(attribute), self.class.easy_attribute_definition(attribute).) end end end |
#attr_money(*args) ⇒ Object
Public: Alias of attr_fixed for a money type with suffix of ‘money’ and precision of 2.
args - list of money attributes options - hash of attr_fixed options.
Examples:
attr_money :price
attr_money :wager, method_suffix:'quatloos', precision:1, unit:'QL'
Adds the following helpers
price_money() #=> "42.00"
price_money=("3.8") #=> 380
price_float() #=> 3.8
1031 1032 1033 1034 1035 1036 |
# File 'lib/easy_attributes.rb', line 1031 def attr_money(*args) opt = args.last.is_a?(Hash) ? args.pop : {} opt = {method_suffix:'money', precision:2}.merge(opt) args << opt attr_fixed(*args) end |
#attr_shared(*attributes) ⇒ Object
Public: Imports previously defined definitions into the class by attribute name or Hash mapping.
attributes - List of attributes to import from Config definitions mappings - Hash of atttribute names to a matching alternate name in the Config definitions
Examples
attr_shared :status, :role, widget_type: :general_type, colname: :sharedname
attr_shared employee_status:Employee.status_definition()
Calls attr_values with each definition
790 791 792 793 794 |
# File 'lib/easy_attributes.rb', line 790 def attr_shared(*attributes) mapping = attributes.last.is_a?(Hash) ? attributes.pop : {} attributes.each { |a| install_shared_attribute(a) } mapping.each { |a, shared| install_shared_attribute(a, shared) } end |
#attr_values(attribute, *args) ⇒ Object
Public: Defines an attribute with a Hash of symbolic synonyms for the values.
attribute - symbolic name of the attribute values - a hash of .… mappings
a optional key of :options=>{name:value} defines any options for the attribute
Examples
attr_values :status, active:1, inactive:2
Creates these instance methods (for a “status” attribute):
status_sym() # Returns the symbolic name instead of value
status_sym=(:inactive) # Used for setting the attrivute by symbolic name instead
status_in(symbol, ...) # Returns true if the attribute symbol is in the list of symbols
status_cmp(symbol) # Returns the comparison of the value <=> symbol
And these class methods:
status_definition()
Returns the EasyAttributes::Definition for the attribute, on which you can call cool things like
value_of(), symbol_of(), select_options(), etc.
Returns nothing
705 706 707 708 709 |
# File 'lib/easy_attributes.rb', line 705 def attr_values(attribute, *args) #defn = Definition.find_or_create(attribute, *args) defn = Definition.new(attribute, *args) easy_attribute_accessors(attribute, defn) end |
#define_easy_attribute_definition ⇒ Object
Adds once to class: Returns the EasyAttribute::Definition of the passed
900 901 902 903 904 905 906 |
# File 'lib/easy_attributes.rb', line 900 def define_easy_attribute_definition unless self.respond_to?(:easy_attribute_definition) define_singleton_method(:easy_attribute_definition) do |attrib| @easy_attribute_definitions.fetch(attrib.to_sym) { raise "EasyAttribute #{attrib} not found" } end end end |
#easy_attribute_accessors(attribute, defn) ⇒ Object
Private: Creates attribute accessors for the attribute /definition for attr_values
Creates these methods dynamically on the host class
self.<attribute>_definition()
<attribute>_sym()
<attribute>_sym=()
<attribute>_in()
<attribute>_cmp()
If Config.constantize, create ATTRIBUTE_SYMBOL=value constants
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 |
# File 'lib/easy_attributes.rb', line 813 def easy_attribute_accessors(attribute, defn) attribute = attribute.to_sym @easy_attribute_definitions ||= {} @easy_attribute_definitions[attribute] = defn opt = defn. code = '' if (EasyAttributes::Config.orm == :active_model || opt[:orm] == :active_model) && self.respond_to?(:validates_inclusion_of) self.validates_inclusion_of attribute, :in=>defn.symbols.values # Add named_scope (scope) for each value if opt[:named_scope] defn.symbols.each { |k,v| code += "named_scope :#{k}, :conditions=>{:#{attribute}=>#{v.inspect}}\n" } end if opt[:scope] defn.symbols.each { |k,v| code += "scope :#{k}, where({:#{attribute}=>#{v.inspect}})\n" } end else attr_accessor attribute end #------------------------------------------------------------------------ # Class Methods #------------------------------------------------------------------------ define_easy_attribute_definition # <attribute>_options() Returns an array of (HTML Select) option pairs # => [["Option Name", :symbol], ...] self.define_singleton_method("#{attribute}_options") do |*args| easy_attribute_definition(attribute).select_option_symbols(*args) end # <attribute>_of(:sym [,:default_sym]) Returns the symbol/value hash for the attribute self.define_singleton_method("#{attribute}_of") do |*args, &block| easy_attribute_definition(attribute).symbols.fetch(args.first.to_sym) do |sym| if args.size>1 easy_attribute_definition(attribute).symbols.fetch(args[1].to_sym, &block) else raise "#{attribute} symbolic name #{sym} not found" end end end # Define Constants Model::ATTRIBUTE_SYMBOL = value if Config::constantize easy_attribute_definition(attribute).symbols.each do |sym, value| const_set("#{attribute.upcase}_#{sym.to_s.upcase}", value) end end #------------------------------------------------------------------------ # Instance Methods #------------------------------------------------------------------------ # <attribute>_definition() # Returns the definition ojbect for the easy attribute define_method("#{attribute}_definition") do self.class.easy_attribute_definition(attribute) end # <attribute>_sym() # Returns the symbolic name of the current value of "attribute" define_method("#{attribute}_sym") do self.class.easy_attribute_definition(attribute).symbol_of(self.send(attribute)) end # <attribute>_sym=(new_symbol) # Sets the value of "attribute" to the associated value of the passed symbolic name define_method("#{attribute}_sym=") do |sym| self.send("#{attribute}=", self.class.easy_attribute_definition(attribute).value_of(sym)) end # <attribute>_in(*names) # Returns true if the symbolic name of the current value of "attribute" is in the list of names. define_method("#{attribute}_in") do |*args| self.class.easy_attribute_definition(attribute).value_in(self.send(attribute),*args) end # <attribute>_cmp(other) # Standard "cmp" or <=> compare for "attribute" against a symbolic name. define_method("#{attribute}_cmp") do |other| self.class.easy_attribute_definition(attribute).cmp(self.send(attribute),other) end end |
#install_shared_attribute(name, shared_name = nil) ⇒ Object
796 797 798 799 800 |
# File 'lib/easy_attributes.rb', line 796 def install_shared_attribute(name, shared_name=nil) shared_name ||= name defn = Definition.find_or_create(shared_name) easy_attribute_accessors(name, defn) end |