lib/has_eav.rb in has_eav-1.1.5 vs lib/has_eav.rb in has_eav-1.2.0

- old
+ new

@@ -7,43 +7,58 @@ module ClassMethods # Specify that the ActiveModel is an EAV model # # == Usage - # # specifiy eav_attributes at instance level - # has_eav :through => :some_class_with_name_and_value_attributes - # def available_eav_attributes - # case self.origin - # when "remote" - # %(remote_ip user_agent) - # when "local" - # %(user) - # end + [ :uniq_id ] - # end + # # specifiy eav_attributes at instance level + # has_eav :through => :some_class_with_name_and_value_attributes + # def available_eav_attributes + # case self.origin + # when "remote" + # %(remote_ip user_agent) + # when "local" + # %(user) + # end + [ :uniq_id ] + # end # - # # specify some eav_attributes at class level - # has_eav :through => "BoundAttribute" do - # eav_attribute :remote_ip - # eav_attribute :uniq_id - # end + # # specify some eav_attributes at class level + # has_eav :through => "BoundAttribute" do + # eav_attribute :remote_ip + # eav_attribute :uniq_id + # end # + # # specify more attributes in an STI class + # class ItalianJob < Job + # has_eav do + # eav_attribute :mini_driver + # end + # end + # # == Mixing class and instance defined EAV attributes # You can define EAV attributes both in class and instance context and # they will be both adhered # def has_eav opts={}, &block + if self.superclass != ActiveRecord::Base && (opts.nil? || opts.empty?) + @eav_attributes = {} + yield + return + end + klass = opts.delete :through klass = klass.to_s if klass.is_a? Symbol klass = klass.camelize raise( "Eav Class cannot be nil. Specify a class using " + "has_eav :through => :class" ) if klass.blank? + opts[:class_name] = klass + class_eval do - has_many :eav_attributes, :class_name => klass + has_many :eav_attributes, opts after_save :save_eav_attributes end @eav_class = klass.constantize @eav_attributes = {} @@ -55,18 +70,18 @@ # Add an other attribute to the class list def eav_attribute name, type = String name = name.to_s if !name.is_a? String - self.class_eav_attributes[name] = type + @eav_attributes[name] = type end # class accessor - when the superclass != AR::Base asume we are in STI # mode def class_eav_attributes # :nodoc: superclass != ActiveRecord::Base ? - superclass.class_eav_attributes : + superclass.class_eav_attributes.merge(@eav_attributes || {}) : @eav_attributes end # class accessor - when the superclass != AR::Base asume we are in STI # mode @@ -212,20 +227,19 @@ def cast_eav_value value, attribute # :nodoc: attributes = self.class_eav_attributes.stringify_keys return value unless attributes.keys.include?(attribute) return value if attributes[attribute] == String # no need for casting - begin # for core types [eg: Integer '12'] eval("#{attributes[attribute]} '#{value}'") rescue begin - attributes[attribute].new(value) + attributes[attribute].parse(value) rescue begin - attributes[attribute].parse(value) + attributes[attribute].new(value) rescue value end end end