Module: SnailTrail::VersionConcern::ClassMethods

Defined in:
lib/snail_trail/version_concern.rb

Overview

:nodoc:

Instance Method Summary collapse

Instance Method Details

#between(start_time, end_time) ⇒ Object



53
54
55
56
57
58
# File 'lib/snail_trail/version_concern.rb', line 53

def between(start_time, end_time)
  where(
    arel_table[:created_at].gt(start_time).
    and(arel_table[:created_at].lt(end_time))
  ).order(timestamp_sort_order)
end

#createsObject



37
38
39
# File 'lib/snail_trail/version_concern.rb', line 37

def creates
  where event: %w[create batch_create]
end

#destroysObject



45
46
47
# File 'lib/snail_trail/version_concern.rb', line 45

def destroys
  where event: %w[destroy batch_destroy]
end

#not_createsObject



49
50
51
# File 'lib/snail_trail/version_concern.rb', line 49

def not_creates
  where.not(event: %w[create batch_create])
end

#object_changes_col_is_json?Boolean

Returns whether the ‘object_changes` column is using the `json` type supported by PostgreSQL.

Returns:

  • (Boolean)


178
179
180
# File 'lib/snail_trail/version_concern.rb', line 178

def object_changes_col_is_json?
  %i[json jsonb].include?(columns_hash["object_changes"].try(:type))
end

#object_col_is_json?Boolean

Returns whether the ‘object` column is using the `json` type supported by PostgreSQL.

Returns:

  • (Boolean)


172
173
174
# File 'lib/snail_trail/version_concern.rb', line 172

def object_col_is_json?
  %i[json jsonb].include?(columns_hash["object"].type)
end

#preceding(obj, timestamp_arg = false) ⇒ Object

Returns versions before ‘obj`.

rubocop:disable Style/OptionalBooleanParameter

Parameters:

  • obj
    • a ‘Version` or a timestamp

  • timestamp_arg (defaults to: false)
    • boolean - When true, ‘obj` is a timestamp.

    Default: false.

Returns:

  • ‘ActiveRecord::Relation`



190
191
192
193
194
195
196
# File 'lib/snail_trail/version_concern.rb', line 190

def preceding(obj, timestamp_arg = false)
  if timestamp_arg != true && primary_key_is_int?
    preceding_by_id(obj)
  else
    preceding_by_timestamp(obj)
  end
end

#primary_key_is_int?Boolean

Returns:

  • (Boolean)


164
165
166
167
168
# File 'lib/snail_trail/version_concern.rb', line 164

def primary_key_is_int?
  @primary_key_is_int ||= columns_hash[primary_key].type == :integer
rescue StandardError # TODO: Rescue something more specific
  true
end

#subsequent(obj, timestamp_arg = false) ⇒ Object

Returns versions after ‘obj`.

rubocop:disable Style/OptionalBooleanParameter

Parameters:

  • obj
    • a ‘Version` or a timestamp

  • timestamp_arg (defaults to: false)
    • boolean - When true, ‘obj` is a timestamp.

    Default: false.

Returns:

  • ‘ActiveRecord::Relation`



207
208
209
210
211
212
213
# File 'lib/snail_trail/version_concern.rb', line 207

def subsequent(obj, timestamp_arg = false)
  if timestamp_arg != true && primary_key_is_int?
    subsequent_by_id(obj)
  else
    subsequent_by_timestamp(obj)
  end
end

#timestamp_sort_order(direction = "asc") ⇒ Object

Defaults to using the primary key as the secondary sort order if possible.



62
63
64
# File 'lib/snail_trail/version_concern.rb', line 62

def timestamp_sort_order(direction = "asc")
  [(arel_table[primary_key].send(direction.downcase) if primary_key_is_int?)].compact
end

#updatesObject



41
42
43
# File 'lib/snail_trail/version_concern.rb', line 41

def updates
  where event: %w[update batch_update]
end

#where_attribute_changes(attribute) ⇒ Object

Given an attribute like ‘“name”`, query the `versions.object_changes` column for any changes that modified the provided attribute.



70
71
72
73
74
75
76
# File 'lib/snail_trail/version_concern.rb', line 70

def where_attribute_changes(attribute)
  unless attribute.is_a?(String) || attribute.is_a?(Symbol)
    raise ArgumentError, "expected to receive a String or Symbol"
  end

  Queries::Versions::WhereAttributeChanges.new(self, attribute).execute
end

#where_object(args = {}) ⇒ Object

Given a hash of attributes like ‘name: ’Joan’‘, query the `versions.objects` column.

“‘ SELECT “versions”.* FROM “versions” WHERE (“versions”.“object” LIKE ’% name: Joan %‘) “`

This is useful for finding versions where a given attribute had a given value. Imagine, in the example above, that Joan had changed her name and we wanted to find the versions before that change.

Based on the data type of the ‘object` column, the appropriate SQL operator is used. For example, a text column will use `like`, and a jsonb column will use `@>`.

Raises:

  • (ArgumentError)


98
99
100
101
# File 'lib/snail_trail/version_concern.rb', line 98

def where_object(args = {})
  raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash)
  Queries::Versions::WhereObject.new(self, args).execute
end

#where_object_changes(args = {}) ⇒ Object

Given a hash of attributes like ‘name: ’Joan’‘, query the `versions.objects_changes` column.

“‘ SELECT “versions”.* FROM “versions” WHERE .. (“versions”.“object_changes” LIKE ’% name:

  • Joan

%‘ OR “versions”.“object_changes” LIKE ’% name: -%

  • Joan

%‘) “`

This is useful for finding versions immediately before and after a given attribute had a given value. Imagine, in the example above, that someone changed their name to Joan and we wanted to find the versions immediately before and after that change.

Based on the data type of the ‘object` column, the appropriate SQL operator is used. For example, a text column will use `like`, and a jsonb column will use `@>`.

Raises:

  • (ArgumentError)


129
130
131
132
# File 'lib/snail_trail/version_concern.rb', line 129

def where_object_changes(args = {})
  raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash)
  Queries::Versions::WhereObjectChanges.new(self, args).execute
end

#where_object_changes_from(args = {}) ⇒ Object

Given a hash of attributes like ‘name: ’Joan’‘, query the `versions.objects_changes` column for changes where the version changed from the hash of attributes to other values.

This is useful for finding versions where the attribute started with a known value and changed to something else. This is in comparison to ‘where_object_changes` which will find both the changes before and after.

Raises:

  • (ArgumentError)


144
145
146
147
# File 'lib/snail_trail/version_concern.rb', line 144

def where_object_changes_from(args = {})
  raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash)
  Queries::Versions::WhereObjectChangesFrom.new(self, args).execute
end

#where_object_changes_to(args = {}) ⇒ Object

Given a hash of attributes like ‘name: ’Joan’‘, query the `versions.objects_changes` column for changes where the version changed to the hash of attributes from other values.

This is useful for finding versions where the attribute started with an unknown value and changed to a known value. This is in comparison to ‘where_object_changes` which will find both the changes before and after.

Raises:

  • (ArgumentError)


159
160
161
162
# File 'lib/snail_trail/version_concern.rb', line 159

def where_object_changes_to(args = {})
  raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash)
  Queries::Versions::WhereObjectChangesTo.new(self, args).execute
end

#with_item_keys(item_type, item_id) ⇒ Object



33
34
35
# File 'lib/snail_trail/version_concern.rb', line 33

def with_item_keys(item_type, item_id)
  where item_type: item_type, item_id: item_id
end