Class: SlimScrooge::MonitoredHash

Inherits:
Hash
  • Object
show all
Defined in:
lib/slim_scrooge/monitored_hash.rb

Overview

A MonitoredHash allows us to return only some columns into the @attributes of an ActiveRecord model object, but to notice when an attribute that wasn’t fetched is accessed.

Also, when a result is first fetched for a particular callsite, we monitor all the columns so that we can immediately learn which columns are needed.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Hash

#c_update, #update

Instance Attribute Details

#callsiteObject

Returns the value of attribute callsite.



12
13
14
# File 'lib/slim_scrooge/monitored_hash.rb', line 12

def callsite
  @callsite
end

#monitored_columnsObject

Returns the value of attribute monitored_columns.



12
13
14
# File 'lib/slim_scrooge/monitored_hash.rb', line 12

def monitored_columns
  @monitored_columns
end

#result_setObject

Returns the value of attribute result_set.



12
13
14
# File 'lib/slim_scrooge/monitored_hash.rb', line 12

def result_set
  @result_set
end

Class Method Details

.[](monitored_columns, unmonitored_columns, callsite) ⇒ Object

Create a monitored hash. The unmonitored_columns are accessed like a regular hash. The monitored columns kept separately, and new_column_access is called before they are returned.



18
19
20
21
22
23
24
# File 'lib/slim_scrooge/monitored_hash.rb', line 18

def self.[](monitored_columns, unmonitored_columns, callsite)
  hash = MonitoredHash.new {|hash, key| hash.new_column_access(key)}
  hash.monitored_columns = monitored_columns
  hash.merge!(unmonitored_columns)
  hash.callsite = callsite
  hash
end

._load(str) ⇒ Object



84
85
86
# File 'lib/slim_scrooge/monitored_hash.rb', line 84

def self._load(str)
  Marshal.load(str)
end

Instance Method Details

#[]=(name, value) ⇒ Object

Reload if needed before allowing assignment



40
41
42
43
44
45
46
47
48
# File 'lib/slim_scrooge/monitored_hash.rb', line 40

def []=(name, value)
  if has_key?(name)
    return super
  elsif !@result_set.nil? && @callsite.columns_hash.has_key?(name)
    @result_set.reload!
    Callsites.add_seen_column(@callsite, name)
  end
  @monitored_columns[name] = value
end

#_dump(depth) ⇒ Object

Marshal Dump a real hash - can’t dump a monitored hash due to default proc



80
81
82
# File 'lib/slim_scrooge/monitored_hash.rb', line 80

def _dump(depth)
  Marshal.dump(to_hash)
end

#freezeObject



71
72
73
74
75
# File 'lib/slim_scrooge/monitored_hash.rb', line 71

def freeze
  @result_set.reload! unless @result_set.nil?
  @monitored_columns.freeze
  super
end

#has_key?(name) ⇒ Boolean Also known as: include?

Check for a column name

Returns:

  • (Boolean)


58
59
60
# File 'lib/slim_scrooge/monitored_hash.rb', line 58

def has_key?(name)
  !@result_set.nil? ? @callsite.columns_hash.has_key?(name) : super || @monitored_columns.has_key?(name)
end

#keysObject

Returns the column names



52
53
54
# File 'lib/slim_scrooge/monitored_hash.rb', line 52

def keys
  !@result_set.nil? ? @callsite.columns_hash.keys : super | @monitored_columns.keys
end

#new_column_access(name) ⇒ Object

Called when an unknown column is requested, through the default proc. If the column requested is valid, and the result set is not completely loaded, then we reload. Otherwise just note the column with add_seen_column.



30
31
32
33
34
35
36
# File 'lib/slim_scrooge/monitored_hash.rb', line 30

def new_column_access(name)
  if @callsite.columns_hash.has_key?(name)
    @result_set.reload! if !@result_set.nil? && name != @callsite.primary_key
    Callsites.add_seen_column(@callsite, name)
  end
  @monitored_columns[name]
end

#to_hashObject

Called by Hash#update when reload is called on an ActiveRecord object



66
67
68
69
# File 'lib/slim_scrooge/monitored_hash.rb', line 66

def to_hash
  @result_set.reload! unless @result_set.nil?
  @monitored_columns.merge(self)
end