aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/relation')
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb20
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb54
2 files changed, 21 insertions, 53 deletions
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index dea7542f03..236d36e15f 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -175,13 +175,21 @@ module ActiveRecord
# See also #ids.
#
def pluck(*column_names)
- _pluck(column_names, @klass.allow_unsafe_raw_sql == :enabled)
- end
+ if loaded? && (column_names.map(&:to_s) - @klass.attribute_names_and_aliases).empty?
+ return records.pluck(*column_names)
+ end
- # Same as #pluck but allows raw SQL regardless of `allow_unsafe_raw_sql`
- # config setting.
- def unsafe_raw_pluck(*column_names)
- _pluck(column_names, true)
+ if has_include?(column_names.first)
+ construct_relation_for_association_calculations.pluck(*column_names)
+ else
+ enforce_raw_sql_whitelist(column_names)
+ relation = spawn
+ relation.select_values = column_names.map { |cn|
+ @klass.respond_to_attribute?(cn) ? arel_attribute(cn) : cn
+ }
+ result = klass.connection.select_all(relation.arel, nil, bound_attributes)
+ result.cast_values(klass.attribute_types)
+ end
end
# Pluck all the ID's for the relation using the table's primary key
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 63b1d8e154..4c63d0450a 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -295,22 +295,9 @@ module ActiveRecord
spawn.order!(*args)
end
- # Same as #order but allows raw SQL regardless of `allow_unsafe_raw_sql`
- # config setting.
- def unsafe_raw_order(*args) # :nodoc:
- check_if_method_has_arguments!(:order, args)
- spawn.unsafe_raw_order!(*args)
- end
-
# Same as #order but operates on relation in-place instead of copying.
def order!(*args) # :nodoc:
- restrict_order_args(args) unless klass.allow_unsafe_raw_sql == :enabled
- unsafe_raw_order!(*args)
- end
-
- # Same as #order! but allows raw SQL regardless of `allow_unsafe_raw_sql`
- # config setting.
- def unsafe_raw_order!(*args) # :nodoc:
+ enforce_raw_sql_whitelist(column_names_from_order_arguments(args))
preprocess_order_args(args)
self.order_values += args
@@ -331,22 +318,9 @@ module ActiveRecord
spawn.reorder!(*args)
end
- # Same as #reorder but allows raw SQL regardless of `allow_unsafe_raw_sql`
- # config setting.
- def unsafe_raw_reorder(*args) # :nodoc:
- check_if_method_has_arguments!(:reorder, args)
- spawn.unsafe_raw_reorder!(*args)
- end
-
# Same as #reorder but operates on relation in-place instead of copying.
def reorder!(*args) # :nodoc:
- restrict_order_args(args) unless klass.allow_unsafe_raw_sql == :enabled
- unsafe_raw_reorder!
- end
-
- # Same as #reorder! but allows raw SQL regardless of `allow_unsafe_raw_sql`
- # config setting.
- def unsafe_raw_reorder!(*args) # :nodoc:
+ enforce_raw_sql_whitelist(column_names_from_order_arguments(args))
preprocess_order_args(args)
self.reordering_value = true
@@ -946,6 +920,11 @@ module ActiveRecord
private
+ # Extract column names from arguments passed to #order or #reorder.
+ def column_names_from_order_arguments(args)
+ args.flat_map { |arg| arg.is_a?(Hash) ? arg.keys : arg }
+ end
+
def assert_mutability!
raise ImmutableRelation if @loaded
raise ImmutableRelation if defined?(@arel) && @arel
@@ -1169,25 +1148,6 @@ module ActiveRecord
end.flatten!
end
- # Only allow column names and directions as arguments to #order and
- # #reorder. Other arguments will cause an ArugmentError to be raised.
- def restrict_order_args(args)
- args = args.dup
- orderings = args.extract_options!
- columns = args | orderings.keys
-
- unrecognized = columns.reject { |c| klass.respond_to_attribute?(c) }
- if unrecognized.any?
- raise ArgumentError, "Invalid order column: #{unrecognized}"
- end
-
- # TODO: find a better list of modifiers.
- unrecognized = orderings.values.reject { |d| VALID_DIRECTIONS.include?(d.to_s) }
- if unrecognized.any?
- raise ArgumentError, "Invalid order direction: #{unrecognized}"
- end
- end
-
# Checks to make sure that the arguments are not blank. Note that if some
# blank-like object were initially passed into the query method, then this
# method will not raise an error.