module PaperTrail::VersionConcern::ClassMethods

Public Instance Methods

between(start_time, end_time) click to toggle source
# File lib/paper_trail/version_concern.rb, line 52
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
creates() click to toggle source
# File lib/paper_trail/version_concern.rb, line 36
def creates
  where event: "create"
end
destroys() click to toggle source
# File lib/paper_trail/version_concern.rb, line 44
def destroys
  where event: "destroy"
end
not_creates() click to toggle source
# File lib/paper_trail/version_concern.rb, line 48
def not_creates
  where.not(event: "create")
end
object_changes_col_is_json?() click to toggle source

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

# File lib/paper_trail/version_concern.rb, line 179
def object_changes_col_is_json?
  %i[json jsonb].include?(columns_hash["object_changes"].try(:type))
end
object_col_is_json?() click to toggle source

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

# File lib/paper_trail/version_concern.rb, line 173
def object_col_is_json?
  %i[json jsonb].include?(columns_hash["object"].type)
end
preceding(obj, timestamp_arg = false) click to toggle source

Returns versions before ‘obj`.

@param obj - a ‘Version` or a timestamp @param timestamp_arg - boolean - When true, `obj` is a timestamp.

Default: false.

@return ‘ActiveRecord::Relation` @api public rubocop:disable Style/OptionalBooleanParameter

# File lib/paper_trail/version_concern.rb, line 191
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?() click to toggle source
# File lib/paper_trail/version_concern.rb, line 165
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) click to toggle source

Returns versions after ‘obj`.

@param obj - a ‘Version` or a timestamp @param timestamp_arg - boolean - When true, `obj` is a timestamp.

Default: false.

@return ‘ActiveRecord::Relation` @api public rubocop:disable Style/OptionalBooleanParameter

# File lib/paper_trail/version_concern.rb, line 208
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") click to toggle source

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

# File lib/paper_trail/version_concern.rb, line 61
def timestamp_sort_order(direction = "asc")
  [arel_table[:created_at].send(direction.downcase)].tap do |array|
    array << arel_table[primary_key].send(direction.downcase) if primary_key_is_int?
  end
end
updates() click to toggle source
# File lib/paper_trail/version_concern.rb, line 40
def updates
  where event: "update"
end
where_attribute_changes(attribute) click to toggle source

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

@api public

# File lib/paper_trail/version_concern.rb, line 71
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 = {}) click to toggle source

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 `@>`.

@api public

# File lib/paper_trail/version_concern.rb, line 99
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 = {}) click to toggle source

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 `@>`.

@api public

# File lib/paper_trail/version_concern.rb, line 130
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 = {}) click to toggle source

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.

@api public

# File lib/paper_trail/version_concern.rb, line 145
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 = {}) click to toggle source

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.

@api public

# File lib/paper_trail/version_concern.rb, line 160
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) click to toggle source
# File lib/paper_trail/version_concern.rb, line 32
def with_item_keys(item_type, item_id)
  where item_type: item_type, item_id: item_id
end

Private Instance Methods

preceding_by_id(obj) click to toggle source

@api private

# File lib/paper_trail/version_concern.rb, line 220
def preceding_by_id(obj)
  where(arel_table[primary_key].lt(obj.id)).order(arel_table[primary_key].desc)
end
preceding_by_timestamp(obj) click to toggle source

@api private

# File lib/paper_trail/version_concern.rb, line 225
def preceding_by_timestamp(obj)
  obj = obj.send(:created_at) if obj.is_a?(self)
  where(arel_table[:created_at].lt(obj)).
    order(timestamp_sort_order("desc"))
end
subsequent_by_id(version) click to toggle source

@api private

# File lib/paper_trail/version_concern.rb, line 232
def subsequent_by_id(version)
  where(arel_table[primary_key].gt(version.id)).order(arel_table[primary_key].asc)
end
subsequent_by_timestamp(obj) click to toggle source

@api private

# File lib/paper_trail/version_concern.rb, line 237
def subsequent_by_timestamp(obj)
  obj = obj.send(:created_at) if obj.is_a?(self)
  where(arel_table[:created_at].gt(obj)).order(timestamp_sort_order)
end