Created
April 25, 2019 07:05
-
-
Save inopinatus/c3996fa976a26aa1e1011fb2a567fd4c to your computer and use it in GitHub Desktop.
SHA digest queries for ActiveRecord + postgresql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
enables
MyModel.where(text: Digest::SHA256.new.update(text))
c.f. https://www.reddit.com/r/rails/comments/bgtn9o/best_and_fastest_way_to_search_for_text_in/elouksy/