Skip to content

Instantly share code, notes, and snippets.

@inopinatus
Created May 10, 2020 06:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inopinatus/f25f72b95f0e4e834f4998462105a69b to your computer and use it in GitHub Desktop.
Save inopinatus/f25f72b95f0e4e834f4998462105a69b to your computer and use it in GitHub Desktop.
Digest predicates
module DigestQueries
def predicate_builder
@predicate_builder ||= super.tap do |pb|
pb.register_handler(Digest::Instance, DigestHandler.new(pb))
end
end
class DigestHandler
def initialize(predicate_builder)
@predicate_builder = predicate_builder
end
def call(attribute, value)
type = case value
when Digest::MD5; 'md5'
when Digest::SHA1; 'sha1'
when Digest::SHA2; "sha#{value.length * 8}"
when Digest::SHA256; 'sha256'
when Digest::SHA384; 'sha384'
when Digest::SHA512; 'sha512'
else
raise ArgumentError, "Did not recognise #{value.inspect} as a Digest object"
end
binvalue = ActiveModel::Type::Binary::Data.new(value.digest)
bind = predicate_builder.build_bind_attribute(attribute.name, binvalue)
digest(attribute, type).eq(bind)
end
private
attr_reader :predicate_builder
def digest(attribute, type)
Arel::Nodes::NamedFunction.new("digest", [attribute, Arel::Nodes::Quoted.new(type)])
end
end
end
ActiveRecord::Base.extend(DigestQueries)
@inopinatus
Copy link
Author

text_digest = Digest::SHA256.new.update(text)
Model.where(text: text_digest)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment