Refactor CanLookup concern

This commit is contained in:
Ryan Lue 2018-07-04 20:57:10 +08:00
parent 2b31311bea
commit 743bbcd794

View file

@ -2,7 +2,6 @@
module ApplicationModel::CanLookup module ApplicationModel::CanLookup
extend ActiveSupport::Concern extend ActiveSupport::Concern
# methods defined here are going to extend the class, not the instance of it
class_methods do class_methods do
=begin =begin
@ -20,78 +19,31 @@ returns
=end =end
def lookup(data) def lookup(**attr)
if data[:id] attr.transform_keys!(&:to_sym).slice!(*lookup_keys)
cache = cache_get(data[:id]) raise ArgumentError, "Valid lookup attribute required (#{lookup_keys.join(', ')})" if attr.empty?
return cache if cache raise ArgumentError, "Multiple lookup attributes given (#{attr.keys.join(', ')})" if attr.many?
record = find_by(id: data[:id]) record = cache_get(attr.values.first)
cache_set(data[:id], record) record ||= find_and_save_to_cache_by(attr)
return record end
elsif data[:name]
cache = cache_get(data[:name])
return cache if cache
# do lookup with == to handle case insensitive databases private
records = if Rails.application.config.db_case_sensitive
where('LOWER(name) = LOWER(?)', data[:name])
else
where(name: data[:name])
end
records.each do |loop_record|
next if loop_record.name != data[:name]
cache_set(data[:name], loop_record)
return loop_record
end
return
elsif data[:login]
cache = cache_get(data[:login])
return cache if cache
# do lookup with == to handle case insensitive databases def lookup_keys
records = if Rails.application.config.db_case_sensitive @lookup_keys ||= %i[id name login email number] & attribute_names.map(&:to_sym)
where('LOWER(login) = LOWER(?)', data[:login]) end
else
where(login: data[:login])
end
records.each do |loop_record|
next if loop_record.login != data[:login]
cache_set(data[:login], loop_record)
return loop_record
end
return
elsif data[:email]
cache = cache_get(data[:email])
return cache if cache
# do lookup with == to handle case insensitive databases def find_and_save_to_cache_by(attr)
records = if Rails.application.config.db_case_sensitive if !Rails.application.config.db_case_sensitive && string_key?(attr.keys.first)
where('LOWER(email) = LOWER(?)', data[:email]) where(attr).find { |r| r[attr.keys.first] == attr.values.first }
else else
where(email: data[:email]) find_by(attr)
end end.tap { |r| cache_set(attr.values.first, r) }
records.each do |loop_record| end
next if loop_record.email != data[:email]
cache_set(data[:email], loop_record)
return loop_record
end
return
elsif data[:number]
# do lookup with == to handle case insensitive databases def string_key?(key)
records = if Rails.application.config.db_case_sensitive type_for_attribute(key.to_s).type == :string
where('LOWER(number) = LOWER(?)', data[:number])
else
where(number: data[:number])
end
records.each do |loop_record|
next if loop_record.number != data[:number]
return loop_record
end
return
end
raise ArgumentError, 'Need name, id, number, login or email for lookup()'
end end
end end
end end