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


119
120
121
122
123
124
125
126
127
# File 'lib/cacheable_delegator.rb', line 119

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



169
170
171
172
173
174
175
176
# File 'lib/cacheable_delegator.rb', line 169

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



178
179
180
181
182
183
184
185
# File 'lib/cacheable_delegator.rb', line 178

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



187
188
189
190
191
192
# File 'lib/cacheable_delegator.rb', line 187

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

  c
end

#custom_columnsObject



129
130
131
# File 'lib/cacheable_delegator.rb', line 129

def custom_columns
  self._custom_columns
end

#reset_custom_columns!Object



133
134
135
# File 'lib/cacheable_delegator.rb', line 133

def reset_custom_columns!
  self._custom_columns = {}
end

#source_column_namesObject



90
91
92
# File 'lib/cacheable_delegator.rb', line 90

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

#source_columnsObject



86
87
88
# File 'lib/cacheable_delegator.rb', line 86

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

#source_reflectionsObject



94
95
96
# File 'lib/cacheable_delegator.rb', line 94

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cacheable_delegator.rb', line 53

def upgrade_schema!
  # first we create a hash of source_columns
  source_column_hash = source_columns.inject({}) do |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
  end

  # then we merge it with custom_columns
  columns_to_add = source_column_hash.merge(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|
    is_serialize = col_atts.delete(:serialize)
    col col_name, col_atts

    # by default, the client passes in serialize: true for plain serialization
    #  and has the option to pass in serialize: Hash
    if is_serialize
      serialize_klass = (is_serialize == true) ? Object : is_serialize
      serialize col_name, serialize_klass
    end
  end

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

#value_column_namesObject

value columns are just columns that aren’t in EXCLUDED_FIELDS



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

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