Module: ChronoModel::TimeMachine::HistoryModel::ClassMethods

Includes:
TimeQuery, Timeline
Defined in:
lib/chrono_model/time_machine/history_model.rb

Overview

Methods that make up the history interface of the companion History model, automatically built for each Model that includes TimeMachine

Instance Method Summary collapse

Methods included from Timeline

#has_timeline, #quoted_history_fields, #timeline, #timeline_associations, #timeline_associations_from

Instance Method Details

#as_of(time) ⇒ Object

Fetches as of time records.



59
60
61
# File 'lib/chrono_model/time_machine/history_model.rb', line 59

def as_of(time)
  superclass.from(virtual_table_at(time)).as_of_time!(time)
end

#at(time) ⇒ Object

Fetches history record at the given time



73
74
75
# File 'lib/chrono_model/time_machine/history_model.rb', line 73

def at(time)
  time_query(:at, time).from(quoted_table_name).as_of_time!(time)
end

#descends_from_active_record?Boolean

For STI to work, the history model needs to have the exact same semantics as the model it inherits from. However given it is actually inherited, the original AR implementation would return false here. But for STI sake, the history model is located in the same exact hierarchy location as its parent, thus this is defined in this override.

Returns:

  • (Boolean)


110
111
112
# File 'lib/chrono_model/time_machine/history_model.rb', line 110

def descends_from_active_record?
  superclass.descends_from_active_record?
end

#findObject



33
34
35
# File 'lib/chrono_model/time_machine/history_model.rb', line 33

def find(*)
  with_hid_pkey { super }
end

#history?Boolean

To identify this class as the History subclass

Returns:

  • (Boolean)


49
50
51
# File 'lib/chrono_model/time_machine/history_model.rb', line 49

def history?
  true
end

#of(object) ⇒ Object

Fetches the given object history, sorted by history record time by default. Always includes an “as_of_time” column that is either the upper bound of the validity range or now() if history validity is maximum.



88
89
90
# File 'lib/chrono_model/time_machine/history_model.rb', line 88

def of(object)
  where(id: object)
end

#pastObject



44
45
46
# File 'lib/chrono_model/time_machine/history_model.rb', line 44

def past
  time_query(:before, :now).where("NOT upper_inf(#{quoted_table_name}.validity)")
end

#relationObject



53
54
55
# File 'lib/chrono_model/time_machine/history_model.rb', line 53

def relation
  super.as_of_time!(Time.now)
end

#sortedObject

Returns the history sorted by recorded_at



79
80
81
# File 'lib/chrono_model/time_machine/history_model.rb', line 79

def sorted
  all.order(Arel.sql(%[ #{quoted_table_name}."recorded_at" ASC, #{quoted_table_name}."hid" ASC ]))
end

#sti_nameObject

The sti_name method returns the contents of the inheritance column, and it is usually the class name. The inherited class name has the “::History” suffix but that is never going to be present in the data.

As such it is overriden here to return the same contents that the parent would have returned.



99
100
101
# File 'lib/chrono_model/time_machine/history_model.rb', line 99

def sti_name
  superclass.sti_name
end

#time_query(match, time, options = {}) ⇒ Object

In the History context, pre-fill the :on options with the validity interval.



39
40
41
42
# File 'lib/chrono_model/time_machine/history_model.rb', line 39

def time_query(match, time, options = {})
  options[:on] ||= :validity
  super
end

#virtual_table_at(time, table_name: nil) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/chrono_model/time_machine/history_model.rb', line 63

def virtual_table_at(time, table_name: nil)
  virtual_name = table_name ?
    connection.quote_table_name(table_name) :
    superclass.quoted_table_name

  "(#{at(time).to_sql}) #{virtual_name}"
end

#with_hid_pkey(&block) ⇒ Object

HACK. find() and save() require the real history ID. So we are setting it now and ensuring to reset it to the original one after execution completes. FIXME



24
25
26
27
28
29
30
31
# File 'lib/chrono_model/time_machine/history_model.rb', line 24

def with_hid_pkey(&block)
  old = self.primary_key
  self.primary_key = :hid

  block.call
ensure
  self.primary_key = old
end