require 'axle_attributes/has_attributes/json_reader' require 'open-uri' module AxleAttributes module HasAttributes extend ActiveSupport::Concern included do class_attribute :has_attribute_definition_class self.has_attribute_definition_class = '::AxleAttributes::Definition' end module ClassMethods def inherited(child) child.attribute_set = attribute_set.dup child.attributes = attributes.dup super end # Example: # has_attributes( # color: {type: :string, index: true, version: true}, # weight: {type: :integer, version: true} # ) def has_attributes(definitions, default_options = {}) definitions.each do |name, options| has_attribute name, default_options.merge(options) end end def has_attribute(name, options = {}) name = name.to_s definition = attribute_definition_class.new(self, name, options) add_attribute_definition(name, definition) definition.setup! end def add_attribute_definition(name, definition) attributes[name] = definition attribute_set << name end def has_mappings(mappings_hash) mappings_hash.each do |name, mappings| has_mapping name, mappings end end def has_mapping(name, mappings) if mappings.is_a?(Array) mappings = Hash[mappings.map { |v| [v, v.humanize] }] end attributes[name.to_s].mappings = mappings end def attributes_file_root @attributes_file_root ||= Rails.root.join('db', 'attributes') end def attributes_file_root=(pathname) pathname = Pathname.new(pathname) unless pathname.is_a?(Pathname) @attributes_file_root = pathname end def has_attributes_file(filename, options = {}) options[:defaults] ||= {} options[:defaults][:filename] = filename AxleAttributes::HasAttributes::JsonReader.read_definitions(self, read_attributes_file(filename), options) end def attributes @attributes ||= {} end def attributes=(attributes) @attributes = attributes end def attribute_set @attribute_set ||= Set.new end def attribute_set=(attribute_set) @attribute_set = attribute_set end def attribute_definition_class @attribute_definition_class ||= has_attribute_definition_class.constantize end private def read_attributes_file(filename) attributes_file_pathname(filename).read end def attributes_file_pathname(filename) attributes_file_root.join("#{filename}.json") end end end end