aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actioncable/lib/action_cable/channel/base.rb2
-rw-r--r--actioncable/lib/action_cable/server/broadcasting.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb4
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb5
-rw-r--r--activerecord/lib/active_record/relation/where_clause_factory.rb46
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb32
-rw-r--r--activerecord/test/cases/calculations_test.rb5
8 files changed, 58 insertions, 48 deletions
diff --git a/actioncable/lib/action_cable/channel/base.rb b/actioncable/lib/action_cable/channel/base.rb
index 6739a62ba0..718f630f58 100644
--- a/actioncable/lib/action_cable/channel/base.rb
+++ b/actioncable/lib/action_cable/channel/base.rb
@@ -205,7 +205,7 @@ module ActionCable
# Transmit a hash of data to the subscriber. The hash will automatically be wrapped in a JSON envelope with
# the proper channel identifier marked as the recipient.
def transmit(data, via: nil) # :doc:
- logger.info "#{self.class.name} transmitting #{data.inspect.truncate(300)}".tap { |m| m << " (via #{via})" if via }
+ logger.debug "#{self.class.name} transmitting #{data.inspect.truncate(300)}".tap { |m| m << " (via #{via})" if via }
payload = { channel_class: self.class.name, data: data, via: via }
ActiveSupport::Notifications.instrument("transmit.action_cable", payload) do
diff --git a/actioncable/lib/action_cable/server/broadcasting.rb b/actioncable/lib/action_cable/server/broadcasting.rb
index 1fc58baa3e..7fcd6c6587 100644
--- a/actioncable/lib/action_cable/server/broadcasting.rb
+++ b/actioncable/lib/action_cable/server/broadcasting.rb
@@ -38,7 +38,7 @@ module ActionCable
end
def broadcast(message)
- server.logger.info "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect}"
+ server.logger.debug "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect}"
payload = { broadcasting: broadcasting, message: message, coder: coder }
ActiveSupport::Notifications.instrument("broadcast.action_cable", payload) do
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index fd11cab5c0..ae24ce7236 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -452,15 +452,15 @@ module ActiveRecord
@connection
end
- def case_sensitive_comparison(table, attribute, column, value)
- table[attribute].eq(Arel::Nodes::BindParam.new)
+ def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
+ table[attribute].eq(value)
end
- def case_insensitive_comparison(table, attribute, column, value)
+ def case_insensitive_comparison(table, attribute, column, value) # :nodoc:
if can_perform_case_insensitive_comparison_for?(column)
- table[attribute].lower.eq(table.lower(Arel::Nodes::BindParam.new))
+ table[attribute].lower.eq(table.lower(value))
else
- table[attribute].eq(Arel::Nodes::BindParam.new)
+ table[attribute].eq(value)
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 89b4ec9473..18e227b40d 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -619,9 +619,9 @@ module ActiveRecord
SQL
end
- def case_sensitive_comparison(table, attribute, column, value)
+ def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
if column.collation && !column.case_sensitive?
- table[attribute].eq(Arel::Nodes::Bin.new(Arel::Nodes::BindParam.new))
+ table[attribute].eq(Arel::Nodes::Bin.new(value))
else
super
end
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 35c670f1a1..e8aba02611 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -364,15 +364,14 @@ module ActiveRecord
end
def build_count_subquery(relation, column_name, distinct)
- column_alias = Arel.sql("count_column")
subquery_alias = Arel.sql("subquery_for_count")
- aliased_column = aggregate_column(column_name == :all ? 1 : column_name).as(column_alias)
+ aliased_column = aggregate_column(column_name == :all ? "1" : column_name)
relation.select_values = [aliased_column]
subquery = relation.arel.as(subquery_alias)
sm = Arel::SelectManager.new relation.engine
- select_value = operation_over_aggregate_column(column_alias, "count", distinct)
+ select_value = operation_over_aggregate_column(Arel.star, "count", distinct)
sm.project(select_value).from(subquery)
end
end
diff --git a/activerecord/lib/active_record/relation/where_clause_factory.rb b/activerecord/lib/active_record/relation/where_clause_factory.rb
index 737bc278bd..04bee73e8f 100644
--- a/activerecord/lib/active_record/relation/where_clause_factory.rb
+++ b/activerecord/lib/active_record/relation/where_clause_factory.rb
@@ -15,9 +15,12 @@ module ActiveRecord
attributes = klass.send(:expand_hash_conditions_for_aggregates, attributes)
attributes.stringify_keys!
- attributes, binds = predicate_builder.create_binds(attributes)
-
- parts = predicate_builder.build_from_hash(attributes)
+ if perform_case_sensitive?(options = other.last)
+ parts, binds = build_for_case_sensitive(attributes, options)
+ else
+ attributes, binds = predicate_builder.create_binds(attributes)
+ parts = predicate_builder.build_from_hash(attributes)
+ end
when Arel::Nodes::Node
parts = [opts]
else
@@ -32,6 +35,43 @@ module ActiveRecord
protected
attr_reader :klass, :predicate_builder
+
+ private
+
+ def perform_case_sensitive?(options)
+ options && options.key?(:case_sensitive)
+ end
+
+ def build_for_case_sensitive(attributes, options)
+ parts, binds = [], []
+ table = klass.arel_table
+
+ attributes.each do |attribute, value|
+ if reflection = klass._reflect_on_association(attribute)
+ attribute = reflection.foreign_key.to_s
+ value = value[reflection.klass.primary_key] unless value.nil?
+ end
+
+ if value.nil?
+ parts << table[attribute].eq(value)
+ else
+ column = klass.column_for_attribute(attribute)
+
+ binds << predicate_builder.send(:build_bind_param, attribute, value)
+ value = Arel::Nodes::BindParam.new
+
+ predicate = if options[:case_sensitive]
+ klass.connection.case_sensitive_comparison(table, attribute, column, value)
+ else
+ klass.connection.case_insensitive_comparison(table, attribute, column, value)
+ end
+
+ parts << predicate
+ end
+ end
+
+ [parts, binds]
+ end
end
end
end
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 9e8edfbfaf..154cf5f1a4 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -50,37 +50,7 @@ module ActiveRecord
end
def build_relation(klass, attribute, value)
- if reflection = klass._reflect_on_association(attribute)
- attribute = reflection.foreign_key
- value = value.attributes[reflection.klass.primary_key] unless value.nil?
- end
-
- if value.nil?
- return klass.unscoped.where!(attribute => value)
- end
-
- # the attribute may be an aliased attribute
- if klass.attribute_alias?(attribute)
- attribute = klass.attribute_alias(attribute)
- end
-
- attribute_name = attribute.to_s
-
- table = klass.arel_table
- column = klass.columns_hash[attribute_name]
- cast_type = klass.type_for_attribute(attribute_name)
-
- comparison = if !options[:case_sensitive]
- # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
- klass.connection.case_insensitive_comparison(table, attribute, column, value)
- else
- klass.connection.case_sensitive_comparison(table, attribute, column, value)
- end
- klass.unscoped.tap do |scope|
- parts = [comparison]
- binds = [Relation::QueryAttribute.new(attribute_name, value, cast_type)]
- scope.where_clause += Relation::WhereClause.new(parts, binds)
- end
+ klass.unscoped.where!({ attribute => value }, options)
end
def scope_relation(record, relation)
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index b29733a676..0de2fea4c2 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -166,14 +166,15 @@ class CalculationsTest < ActiveRecord::TestCase
end
def test_limit_should_apply_before_count
- accounts = Account.limit(3).where("firm_id IS NOT NULL")
+ accounts = Account.limit(4)
assert_equal 3, accounts.count(:firm_id)
assert_equal 3, accounts.select(:firm_id).count
+ assert_equal 3, accounts.select("firm_id firm_id").count
end
def test_limit_should_apply_before_count_arel_attribute
- accounts = Account.limit(3).where("firm_id IS NOT NULL")
+ accounts = Account.limit(4)
firm_id_attribute = Account.arel_table[:firm_id]
assert_equal 3, accounts.count(firm_id_attribute)