Skip to content

Instantly share code, notes, and snippets.

@MaxPleaner
Created December 27, 2016 21:21
Show Gist options
  • Save MaxPleaner/3a57393d68a26a3f7f549857c7af4139 to your computer and use it in GitHub Desktop.
Save MaxPleaner/3a57393d68a26a3f7f549857c7af4139 to your computer and use it in GitHub Desktop.
Patch ActiveRecord's find_by to prevent errors because of strings passed to numeric columns
# This can be added to config/initializers
class ActiveRecordPatch
# find_by(numeric_column: "foo") converts "foo" to 0 before searching.
# This is probably not desired.
# This patch prevents this behavior
#
def self.validate_input_for_numeric_conditions(class_or_query, conditions)
# iterate over each key-val in the query hash
conditions.each do |column_name, column_val|
# lookup the type of the column corresponding to the key
column_type = class_or_query.columns_hash[column_name.to_s]&.type
# return early if no type is detected;
# it is an invalid column and will error in the original find_by call
break unless column_type
# only handle columns of numeric types
if [:integer, :float, :decimal].include? column_type
# Raise an error if a non-nil, non-numeric value was provided
if column_type != nil && !column_val.is_a?(Numeric)
raise(
ArgumentError,
"non-numeric passed for numeric column #{column_name}"
)
end
end
end
end
end
module ActiveRecord::Core::ClassMethods
def find_by(conditions)
all.find_by conditions
end
end
module ActiveRecord::FinderMethods
def find_by(conditions)
ActiveRecordPatch.validate_input_for_numeric_conditions(self, conditions)
where(conditions).take
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment