mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
validates_uniqueness_of uses database case sensitivity support instead of using ruby
Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
parent
f3da46effa
commit
f7eaab96d3
3 changed files with 23 additions and 27 deletions
|
@ -149,6 +149,10 @@ module ActiveRecord
|
||||||
"INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)"
|
"INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def case_sensitive_equality_operator
|
||||||
|
"="
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
# Returns an array of record hashes with the column names as keys and
|
# Returns an array of record hashes with the column names as keys and
|
||||||
# column values as values.
|
# column values as values.
|
||||||
|
|
|
@ -511,6 +511,10 @@ module ActiveRecord
|
||||||
keys.length == 1 ? [keys.first, nil] : nil
|
keys.length == 1 ? [keys.first, nil] : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def case_sensitive_equality_operator
|
||||||
|
"= BINARY"
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def connect
|
def connect
|
||||||
@connection.reconnect = true if @connection.respond_to?(:reconnect=)
|
@connection.reconnect = true if @connection.respond_to?(:reconnect=)
|
||||||
|
|
|
@ -627,17 +627,23 @@ module ActiveRecord
|
||||||
|
|
||||||
is_text_column = finder_class.columns_hash[attr_name.to_s].text?
|
is_text_column = finder_class.columns_hash[attr_name.to_s].text?
|
||||||
|
|
||||||
if !value.nil? && is_text_column
|
if value.nil?
|
||||||
|
comparison_operator = "IS ?"
|
||||||
|
else
|
||||||
|
comparison_operator = "#{connection.case_sensitive_equality_operator} ?"
|
||||||
|
|
||||||
|
if is_text_column
|
||||||
value = value.to_s
|
value = value.to_s
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sql_attribute = "#{record.class.quoted_table_name}.#{connection.quote_column_name(attr_name)}"
|
||||||
|
|
||||||
if value.nil? || (configuration[:case_sensitive] || !is_text_column)
|
if value.nil? || (configuration[:case_sensitive] || !is_text_column)
|
||||||
condition_sql = "#{record.class.quoted_table_name}.#{attr_name} #{attribute_condition(value)}"
|
condition_sql = "#{sql_attribute} #{comparison_operator}"
|
||||||
condition_params = [value]
|
condition_params = [value]
|
||||||
else
|
else
|
||||||
# sqlite has case sensitive SELECT query, while MySQL/Postgresql don't.
|
condition_sql = "LOWER(#{sql_attribute}) #{comparison_operator}"
|
||||||
# Hence, this is needed only for sqlite.
|
|
||||||
condition_sql = "LOWER(#{record.class.quoted_table_name}.#{attr_name}) #{attribute_condition(value)}"
|
|
||||||
condition_params = [value.downcase]
|
condition_params = [value.downcase]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -654,26 +660,8 @@ module ActiveRecord
|
||||||
condition_params << record.send(:id)
|
condition_params << record.send(:id)
|
||||||
end
|
end
|
||||||
|
|
||||||
results = finder_class.with_exclusive_scope do
|
finder_class.with_exclusive_scope do
|
||||||
connection.select_all(
|
if finder_class.exists?([condition_sql, *condition_params])
|
||||||
construct_finder_sql(
|
|
||||||
:select => "#{connection.quote_column_name(attr_name)}",
|
|
||||||
:from => "#{finder_class.quoted_table_name}",
|
|
||||||
:conditions => [condition_sql, *condition_params]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
unless results.length.zero?
|
|
||||||
found = true
|
|
||||||
|
|
||||||
# As MySQL/Postgres don't have case sensitive SELECT queries, we try to find duplicate
|
|
||||||
# column in ruby when case sensitive option
|
|
||||||
if configuration[:case_sensitive] && finder_class.columns_hash[attr_name.to_s].text?
|
|
||||||
found = results.any? { |a| a[attr_name.to_s] == value.to_s }
|
|
||||||
end
|
|
||||||
|
|
||||||
if found
|
|
||||||
message = record.errors.generate_message(attr_name, :taken, :default => configuration[:message])
|
message = record.errors.generate_message(attr_name, :taken, :default => configuration[:message])
|
||||||
record.errors.add(attr_name, message)
|
record.errors.add(attr_name, message)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue