aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation
diff options
context:
space:
mode:
authorBen Toews <mastahyeti@gmail.com>2017-09-26 09:29:24 -0600
committerMatthew Draper <matthew@trebex.net>2017-11-09 22:41:33 +1030
commit5180fe2cd8233169935065efe8762bd5d7b2709c (patch)
tree73278df63c9938eb19e2ba1b333e07f70be88b0c /activerecord/lib/active_record/relation
parent02a17492a937d4b423590644ad1481b82facd394 (diff)
downloadrails-5180fe2cd8233169935065efe8762bd5d7b2709c.tar.gz
rails-5180fe2cd8233169935065efe8762bd5d7b2709c.tar.bz2
rails-5180fe2cd8233169935065efe8762bd5d7b2709c.zip
allow table name and direction in string order arg
Diffstat (limited to 'activerecord/lib/active_record/relation')
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb31
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb26
2 files changed, 32 insertions, 25 deletions
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 236d36e15f..75795fe493 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -180,14 +180,15 @@ module ActiveRecord
end
if has_include?(column_names.first)
- construct_relation_for_association_calculations.pluck(*column_names)
+ relation = apply_join_dependency
+ relation.pluck(*column_names)
else
- enforce_raw_sql_whitelist(column_names)
+ enforce_raw_sql_whitelist(column_names, whitelist: allowed_pluck_columns)
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 = skip_query_cache_if_necessary { klass.connection.select_all(relation.arel, nil) }
result.cast_values(klass.attribute_types)
end
end
@@ -202,26 +203,10 @@ module ActiveRecord
private
- def _pluck(column_names, unsafe_raw)
- unrecognized = column_names.reject do |cn|
- @klass.respond_to_attribute?(cn)
- end
-
- if loaded? && unrecognized.none?
- records.pluck(*column_names)
- elsif has_include?(column_names.first)
- relation = apply_join_dependency
- relation.pluck(*column_names)
- elsif unsafe_raw || unrecognized.none?
- relation = spawn
- relation.select_values = column_names.map { |cn|
- @klass.respond_to_attribute?(cn) ? arel_attribute(cn) : cn
- }
- result = skip_query_cache_if_necessary { klass.connection.select_all(relation.arel, nil) }
- result.cast_values(klass.attribute_types)
- else
- raise ArgumentError, "Invalid column name: #{unrecognized}"
- end
+ def allowed_pluck_columns
+ @klass.attribute_names_and_aliases.map do |name|
+ [name, "#{table_name}.#{name}"]
+ end.flatten
end
def has_include?(column_name)
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index f3b44d19d6..094e5aa733 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -297,7 +297,11 @@ module ActiveRecord
# Same as #order but operates on relation in-place instead of copying.
def order!(*args) # :nodoc:
- @klass.enforce_raw_sql_whitelist(column_names_from_order_arguments(args))
+ @klass.enforce_raw_sql_whitelist(
+ column_names_from_order_arguments(args),
+ whitelist: allowed_order_columns
+ )
+
preprocess_order_args(args)
self.order_values += args
@@ -320,7 +324,11 @@ module ActiveRecord
# Same as #reorder but operates on relation in-place instead of copying.
def reorder!(*args) # :nodoc:
- @klass.enforce_raw_sql_whitelist(column_names_from_order_arguments(args))
+ @klass.enforce_raw_sql_whitelist(
+ column_names_from_order_arguments(args),
+ whitelist: allowed_order_columns
+ )
+
preprocess_order_args(args)
self.reordering_value = true
@@ -920,6 +928,20 @@ module ActiveRecord
private
+ def allowed_order_columns
+ @klass.attribute_names_and_aliases.map do |name|
+ [name, "#{table_name}.#{name}"].map do |name|
+ [
+ name,
+ "#{name} asc",
+ "#{name} ASC",
+ "#{name} desc",
+ "#{name} DESC"
+ ]
+ end
+ end.flatten
+ end
+
# 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 }