Extract query object: Queries::Versions::WhereObject

See recent extraction of WhereObjectChanges for rationale.
This commit is contained in:
Jared Beck 2016-12-13 18:22:38 -05:00
parent 3a7421f8e8
commit 2502098b56
3 changed files with 63 additions and 21 deletions

View File

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

View File

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

View File

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