Module: CacheableDelegator::ClassMethods

Defined in:
lib/cacheable_delegator.rb,
lib/cacheable_delegator.rb

Overview

Builder methods

Instance Method Summary collapse

Instance Method Details

#add_custom_column(col_name, opts = {}) ⇒ Object

Note: This must occur either during the .cache_and_delegate call

or after it. 
.cache_and_delegate *will* empty out custom_columns

And implicitly, @@source_class has already been defined at this point

By default, raise an error if the column_name does not correspond
 to an instance_method of @@source_class, unless the :bespoke option
 is true

opts: Hash of standard ActiveRecord::ConnectionAdapters::Column options

and several custom opts:
  :bespoke => if true, then create this column on CachedRecord even
        if its source_class does not have method_defined?(column_name)
  :serialize => this is passed along to upgrade_schema!
        which will then serialize the column via ActiveRecord.serialize


133
134
135
136
137
138
139
140
141
# File 'lib/cacheable_delegator.rb', line 133

def add_custom_column(col_name, opts={})
  col_str = col_name.to_s
  is_bespoke = opts.delete :bespoke     
  if !(self.source_class.method_defined?(col_str) || self.source_class.new.respond_to?(col_str)) && is_bespoke != true
    raise NonExistentInstanceMethod, "Since :bespoke != true, instance of #{self.source_class} was expected to respond_to? :#{col_str}"
  end

  custom_columns[col_name.to_s] = opts
end

#build_attributes_hash(source_obj) ⇒ Object



183
184
185
186
187
188
189
190
# File 'lib/cacheable_delegator.rb', line 183

def build_attributes_hash(source_obj)
  att_hsh = self.value_column_names.inject({}) do |hsh, cname|
    if source_obj.respond_to?(cname)
      hsh[cname] = source_obj.send cname
    end
    hsh
  end
end

#build_cache(source_obj) ⇒ Object



192
193
194
195
196
197
198
199
# File 'lib/cacheable_delegator.rb', line 192

def build_cache(source_obj)
  att_hsh = build_attributes_hash(source_obj)

  c_record = self.new(att_hsh)
  c_record.source_record = source_obj

  c_record
end

#cache_and_delegate(klass, opts = {}, &blk) ⇒ Object

this method defines the relation to an existing ActiveModel it does not change the schema unless invoked with the bang!



26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/cacheable_delegator.rb', line 26

def cache_and_delegate(klass, opts={}, &blk)
  cache_record_class(klass)
  # This is why you have to define custom columns in the given block
  # or after the call to cache and delegate

  reset_custom_columns!
  if block_given?
    yield self
  end


  self.source_class
end

#cache_and_delegate!(*args) ⇒ Object

also runs upgrade_schema!



42
43
44
45
46
# File 'lib/cacheable_delegator.rb', line 42

def cache_and_delegate!(*args)
  cache_and_delegate(*args)

  upgrade_schema!
end

#cache_record_class(klass) ⇒ Object

Raises:

  • (ArgumentError)


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

def cache_record_class(klass)
  raise ArgumentError, "Must pass in a class, not a #{klass}" unless klass.is_a?(Class)
  self.source_class = klass
  belongs_to :source_record, class_name: self.source_class.to_s     
end

#create_cache(obj) ⇒ Object



201
202
203
204
205
206
# File 'lib/cacheable_delegator.rb', line 201

def create_cache(obj)
  c = build_cache(obj)
  c.save 

  c
end

#custom_columnsObject



143
144
145
# File 'lib/cacheable_delegator.rb', line 143

def custom_columns
  self._custom_columns
end

#generate_columns_to_upgrade(custom_cols) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/cacheable_delegator.rb', line 84

def generate_columns_to_upgrade(custom_cols)
  # first we create a hash of source_columns
  source_column_hash = source_columns.inject({}){ |shash, source_col|
    source_col_atts = COL_ATTRIBUTES_TO_UPGRADE.inject({}){|hsh, att| hsh[att.to_sym] = source_col.send att; hsh  }
    shash[source_col.name] = source_col_atts

    shash
  }

  # then we merge it with custom_columns
  return source_column_hash.merge(custom_cols)
end

#reset_custom_columns!Object



147
148
149
# File 'lib/cacheable_delegator.rb', line 147

def reset_custom_columns!
  self._custom_columns = {}
end

#set_serialized_columns!Object

a soft method that is run every time the class is loaded just to make sure things are properly serialized



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/cacheable_delegator.rb', line 70

def set_serialized_columns!
  cols = generate_columns_to_upgrade(custom_columns)
  cols.each_pair do |col_name, col_atts|
    if is_serialize = col_atts.delete(:serialize)
    ##  by default, the client passes in serialize: true for plain serialization
    ##  and has the option to pass in serialize: Hash
   
      serialize_klass = (is_serialize == true) ? Object : is_serialize
      serialize col_name, serialize_klass
    end
  end
end

#source_column_namesObject



104
105
106
# File 'lib/cacheable_delegator.rb', line 104

def source_column_names
  source_columns.map{|s| s.name}
end

#source_columnsObject



100
101
102
# File 'lib/cacheable_delegator.rb', line 100

def source_columns
  source_class.columns.reject{|c| EXCLUDED_FIELDS.any?{|f| f.to_s == c.name }}
end

#source_reflectionsObject



108
109
110
# File 'lib/cacheable_delegator.rb', line 108

def source_reflections
  source_class.reflections
end

#upgrade_schema!Object

assumes @@source_class has been set

will call ActiveRecord::Base.serialize based on parameters passed in from



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/cacheable_delegator.rb', line 53

def upgrade_schema!
  # then we merge it with custom_columns
  columns_to_add = generate_columns_to_upgrade(custom_columns)

  # then we add them all in using .col method from active_record_inline_schema
  columns_to_add.each_pair do |col_name, col_atts|
    column_atts_without_serialized_att = col_atts.dup.tap{|h| h.delete :serialize }
    col( col_name, column_atts_without_serialized_att )
  end

  self.auto_upgrade!( :gentle => true )
  self.set_serialized_columns!
end

#value_column_namesObject

value columns are just columns that aren’t in EXCLUDED_FIELDS



113
114
115
# File 'lib/cacheable_delegator.rb', line 113

def value_column_names
  self.column_names - EXCLUDED_FIELDS.map{|f| f.to_s}
end