Module: EavPresenter

Defined in:
lib/eav_presenter.rb

Overview

Usage: Say you have an eav design pattern like this: Person, PersonAttribute and PersonAttrValue You can then define a new class: class EavPerson < Person

include EavPresenter
eav :eav_attr_class => PersonAttribute, :eav_value_class => PersonAttrValue, :eav_entity_foreign_key => "personId",
  :eav_attr_foreign_key => "attrId"

end

The attributes in PersonAttribute will now behave as DB columns. You can also use AR validation macros on them Dirty-tracking will not work in this case. Should be possible to implement. I have tested such a presenter model with scaffolding_extensions plugin only. More testing would be nice.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



15
16
17
# File 'lib/eav_presenter.rb', line 15

def self.included(base)
  base.send(:extend, ClassMethods)
end

Instance Method Details

#load_eav_attr_values_if_not_loadedObject



19
20
21
22
# File 'lib/eav_presenter.rb', line 19

def load_eav_attr_values_if_not_loaded
  entity_foreign_key = self.class.instance_variable_get("@eav_entity_foreign_key")
  @eav_attr_values ||= self.class.instance_variable_get("@eav_value_class").send("find_all_by_#{entity_foreign_key}",self.id)
end

#save_eav_attr_valuesObject



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
# File 'lib/eav_presenter.rb', line 24

def save_eav_attr_values
  self.class.instance_variable_get("@eav_attrs").each { |at|
    eavs = load_eav_attr_values_if_not_loaded
    eav = eavs.find { |i| i.attrId == at.id } #eav in the db
    name = at.eav_attr_name
    entity_foreign_key = self.class.instance_variable_get("@eav_entity_foreign_key")
    attr_foreign_key = self.class.instance_variable_get("@eav_attr_foreign_key")
    eav_value_class = self.class.instance_variable_get("@eav_value_class")
    ivalue = send(name)
    if attribute_changed?(name)
      if eav
        if ivalue.blank?
          #eav needs to be deleted
          eav_value_class.send("find_by_#{attr_foreign_key}_and_#{entity_foreign_key}",at.id,self.id).destroy
        else
          # eav has been modified. needs to be saved.
          eav.value = ivalue
          eav.save!
        end
      else
        #eav needs to be created
        eav_value_class.create({entity_foreign_key.to_sym => self.id, attr_foreign_key.to_sym => at.id, :value => ivalue})
      end
    end
  }
  self.reload # Values have been changed in DB. Better reload them.
  @eav_attr_values = nil
  load_eav_attr_values_if_not_loaded
end