diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 36ea23f0..7872a0b5 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -2,7 +2,7 @@ # one by one as the offenses are removed from the code base. Metrics/AbcSize: - Max: 27 # Goal: 15 + Max: 25 # Goal: 15 Metrics/CyclomaticComplexity: Max: 8 # Goal: 6 diff --git a/lib/paper_trail/queries/versions/where_object.rb b/lib/paper_trail/queries/versions/where_object.rb new file mode 100644 index 00000000..ca6767d6 --- /dev/null +++ b/lib/paper_trail/queries/versions/where_object.rb @@ -0,0 +1,60 @@ +module PaperTrail + module Queries + module Versions + # For public API documentation, see `where_object` in + # `paper_trail/version_concern.rb`. + # @api private + class WhereObject + # - version_model_class - The class that VersionConcern was mixed into. + # - attributes - A `Hash` of attributes and values. See the public API + # documentation for details. + # @api private + def initialize(version_model_class, attributes) + @version_model_class = version_model_class + @attributes = attributes + end + + # @api private + def execute + case @version_model_class.columns_hash["object"].type + when :jsonb + jsonb + when :json + json + else + text + end + end + + private + + # @api private + def json + predicates = [] + values = [] + @attributes.each do |field, value| + predicates.push "object->>? = ?" + values.concat([field, value.to_s]) + end + sql = predicates.join(" and ") + @version_model_class.where(sql, *values) + end + + # @api private + def jsonb + @version_model_class.where("object @> ?", @attributes.to_json) + end + + # @api private + def text + arel_field = @version_model_class.arel_table[:object] + where_conditions = @attributes.map { |field, value| + ::PaperTrail.serializer.where_object_condition(arel_field, field, value) + } + where_conditions = where_conditions.reduce { |a, e| a.and(e) } + @version_model_class.where(where_conditions) + end + end + end + end +end diff --git a/lib/paper_trail/version_concern.rb b/lib/paper_trail/version_concern.rb index c451c9c7..e3510c81 100644 --- a/lib/paper_trail/version_concern.rb +++ b/lib/paper_trail/version_concern.rb @@ -1,5 +1,6 @@ require "active_support/concern" require "paper_trail/attribute_serializers/object_changes_attribute" +require "paper_trail/queries/versions/where_object" require "paper_trail/queries/versions/where_object_changes" module PaperTrail @@ -118,26 +119,7 @@ module PaperTrail # @api public def where_object(args = {}) raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash) - - if columns_hash["object"].type == :jsonb - where("object @> ?", args.to_json) - elsif columns_hash["object"].type == :json - predicates = [] - values = [] - args.each do |field, value| - predicates.push "object->>? = ?" - values.concat([field, value.to_s]) - end - sql = predicates.join(" and ") - where(sql, *values) - else - arel_field = arel_table[:object] - where_conditions = args.map { |field, value| - PaperTrail.serializer.where_object_condition(arel_field, field, value) - } - where_conditions = where_conditions.reduce { |a, e| a.and(e) } - where(where_conditions) - end + Queries::Versions::WhereObject.new(self, args).execute end # Given a hash of attributes like `name: 'Joan'`, query the