Module: ActiveRecord::EavHashes::Util
- Defined in:
- lib/eav_hashes/util.rb
Class Method Summary collapse
-
.class_from_string(str) ⇒ Object
Find a class even if it’s contained in one or more modules.
-
.class_from_string_exists?(str) ⇒ Boolean
Check whether a class exists, even if it’s contained in one or more modules.
-
.create_eav_table_class(options) ⇒ Object
Creates a new type subclassed from ActiveRecord::EavHashes::EavEntry which represents an eav_hash key-value pair.
-
.fill_options_hash(options) ⇒ Object
Fills in any options not explicitly passed to eav_hash_for and creates an EavEntry type for the table.
-
.run_find_expression(key, value, options) ⇒ Object
Searches an EavEntry’s table for the specified key/value pair and returns an array containing the IDs of the models whose eav_hash key/value pair.
-
.sanity_check(options) ⇒ Object
Sanity checks!.
-
.set_constant_from_string(str, val) ⇒ Object
Set a constant from a string, even if the string contains modules.
Class Method Details
.class_from_string(str) ⇒ Object
Find a class even if it’s contained in one or more modules. See stackoverflow.com/questions/3163641/get-a-class-by-name-in-ruby
96 97 98 99 100 |
# File 'lib/eav_hashes/util.rb', line 96 def self.class_from_string(str) str.split('::').inject(Object) do |mod, class_name| mod.const_get(class_name) end end |
.class_from_string_exists?(str) ⇒ Boolean
Check whether a class exists, even if it’s contained in one or more modules.
103 104 105 106 107 108 109 110 |
# File 'lib/eav_hashes/util.rb', line 103 def self.class_from_string_exists?(str) begin class_from_string(str) rescue return false end true end |
.create_eav_table_class(options) ⇒ Object
Creates a new type subclassed from ActiveRecord::EavHashes::EavEntry which represents an eav_hash key-value pair
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/eav_hashes/util.rb', line 45 def self.create_eav_table_class () sanity_check # Don't overwrite an existing type return class_from_string([:entry_class_name].to_s) if class_from_string_exists?([:entry_class_name]) # Create our type klass = set_constant_from_string [:entry_class_name].to_s, Class.new(ActiveRecord::EavHashes::EavEntry) # Fill in the associations and specify the table it belongs to klass.class_eval <<-END_EVAL self.table_name = "#{[:table_name]}" belongs_to :#{[:parent_assoc_name]} END_EVAL return klass end |
.fill_options_hash(options) ⇒ Object
Fills in any options not explicitly passed to eav_hash_for and creates an EavEntry type for the table
13 14 15 16 17 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 |
# File 'lib/eav_hashes/util.rb', line 13 def self.() sanity_check # Generate a unique class name based on the eav_hash's name and owner [:entry_class_name] ||= "#{[:parent_class_name]}_#{[:hash_name]}_entry".camelize.to_sym # Strip "_entries" from the table name if /Entry$/.match [:entry_class_name] [:table_name] ||= [:entry_class_name].to_s.tableize.slice(0..-9).to_sym else [:table_name] ||= [:entry_class_name].to_s.tableize.to_sym end # Create the symbol name for the "belongs_to" association in the entry model [:parent_assoc_name] ||= "#{[:parent_class_name].to_s.underscore}".to_sym # Create the symbol name for the "has_many" association in the parent model [:entry_assoc_name] = [:entry_class_name].to_s.tableize.to_sym # Change slashes to underscores in options to match what's output by the generator # TODO: Refactor table naming into one location [:table_name] = [:table_name].to_s.gsub(/\//,'_').to_sym [:parent_assoc_name] = [:parent_assoc_name].to_s.gsub(/\//,'_').to_sym [:entry_assoc_name] = [:entry_assoc_name].to_s.gsub(/\//,'_').to_sym # Create our custom type if it doesn't exist already [:entry_class] = create_eav_table_class return end |
.run_find_expression(key, value, options) ⇒ Object
Searches an EavEntry’s table for the specified key/value pair and returns an array containing the IDs of the models whose eav_hash key/value pair. You should not run this directly.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/eav_hashes/util.rb', line 69 def self.run_find_expression (key, value, ) sanity_check raise "Can't search for a nil key!" if key.nil? if value.nil? [:entry_class].where( "entry_key = ? and symbol_key = ?", key.to_s, key.is_a?(Symbol) ).pluck("#{[:parent_assoc_name]}_id".to_sym) else val_type = EavEntry.get_value_type value if val_type == EavEntry::SUPPORTED_TYPES[:Object] raise "Can't search by Objects/Hashes/Arrays!" else [:entry_class].where( "entry_key = ? and symbol_key = ? and value = ? and value_type = ?", key.to_s, key.is_a?(Symbol), value.to_s, val_type ).pluck("#{[:parent_assoc_name]}_id".to_sym) end end end |
.sanity_check(options) ⇒ Object
Sanity checks!
6 7 8 9 |
# File 'lib/eav_hashes/util.rb', line 6 def self.sanity_check() raise "options cannot be empty (and you shouldn't be calling this since you left options blank)" if (!.is_a? Hash) or .empty? end |
.set_constant_from_string(str, val) ⇒ Object
Set a constant from a string, even if the string contains modules. Modules are created if necessary.
114 115 116 117 118 119 |
# File 'lib/eav_hashes/util.rb', line 114 def self.set_constant_from_string(str, val) parent = str.deconstantize.split('::').inject(Object) do |mod, class_name| mod.const_defined?(class_name) ? mod.const_get(class_name) : mod.const_set(class_name, Module.new()) end parent.const_set(str.demodulize.to_sym, val) end |