Module: Reamaze::PortableHole::ClassMethods

Defined in:
lib/portable-hole.rb

Overview

Make methods available to ActiveRecord in the class context

Instance Method Summary collapse

Instance Method Details

#portable_hole(eav = :data, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/portable-hole.rb', line 14

def portable_hole(eav = :data, options = {})
  send :include, InstanceMethods

  eav = Helpers.normalize(eav)

  # Create accessor methods to our configuration info
  class << self
    attr_accessor :eav_configuration unless method_defined?(:eav_configuration)
  end

  # Initialize the configuration to an empty hash
  self.eav_configuration = {} if self.eav_configuration.nil?

  # Redefining a configuration once defined should not be allowed
  raise ArgumentError, "#{self} class already has a portal_hole :#{eav} defined" if self.eav_configuration.has_key?(eav)

  eav_configuration[eav] = options

  class_eval <<-end_eval
    # Define the has_many relationship
    has_many :_#{eav}, 
      -> { where(context: '#{eav}').extending(AssociationExtensions) },
      :class_name => 'PortableValue',
      :as         => :model,
      :inverse_of => :model,
      :dependent  => :delete_all

    accepts_nested_attributes_for :_#{eav}, :allow_destroy => true

    def #{eav}
      h = Reamaze::PortableHole::PrefHash.new self, "_#{eav}"
      values = self._#{eav}
      values.each do |v|
        h[v.key] = v.value
      end
      h
    end

    def #{eav}=(hash)
      array = []
      hash = hash.stringify_keys

      deletables = self._#{eav}.reject {|x| hash.keys.include? x.key}

      hash.each do |k, v|
        current = self._#{eav}.detect {|x| x.key == k}
        if current.present?
          if v == '_destroy'
            array << {:id => current.id, :key => k, :value => v, :_destroy => true}
          else
            array << {:id => current.id, :key => k, :value => v}
          end
        else
          array << {:key => k, :value => v, :context => '#{eav}'}
        end
      end

      deletables.each do |x|
        array << {:id => x.id, :_destroy => true}
      end

      self._#{eav}_attributes = array
      hash
    end
  end_eval
end