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.



68
69
70
# File 'lib/chrono_model/time_machine/history_model.rb', line 68

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

Build on an unscoped relation to avoid leaking outer predicates (e.g., through association scopes) into the inner subquery.



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

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

#findObject



42
43
44
# File 'lib/chrono_model/time_machine/history_model.rb', line 42

def find(*)
  with_hid_pkey { super }
end

#history?Boolean

To identify this class as the History subclass

Returns:

  • (Boolean)


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

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.



104
105
106
# File 'lib/chrono_model/time_machine/history_model.rb', line 104

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

#pastObject



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

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

#relationObject



62
63
64
# File 'lib/chrono_model/time_machine/history_model.rb', line 62

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

#sortedObject

Returns the history sorted by recorded_at



95
96
97
# File 'lib/chrono_model/time_machine/history_model.rb', line 95

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

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

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



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

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

#virtual_table_at(time, table_name: nil) ⇒ Object



72
73
74
75
76
77
78
79
80
81
# File 'lib/chrono_model/time_machine/history_model.rb', line 72

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

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

#with_hid_pkeyObject

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



33
34
35
36
37
38
39
40
# File 'lib/chrono_model/time_machine/history_model.rb', line 33

def with_hid_pkey
  old = primary_key
  self.primary_key = 'hid'

  yield
ensure
  self.primary_key = old
end