aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2016-02-04 09:43:21 +1030
committerMatthew Draper <matthew@trebex.net>2016-02-04 09:43:21 +1030
commiteeaf6ee2843775a00579e5996d4081092c567519 (patch)
tree89b632e8b2ab42be322a73d5f08c0e66ed9bb2ca /activerecord
parent13b918d1e9ebe2c609b5479550a35f3665c2acd2 (diff)
parent5952861948a0918b1955202c1ea19589634537dc (diff)
downloadrails-eeaf6ee2843775a00579e5996d4081092c567519.tar.gz
rails-eeaf6ee2843775a00579e5996d4081092c567519.tar.bz2
rails-eeaf6ee2843775a00579e5996d4081092c567519.zip
Merge pull request #23457 from matthewd/arel-attribute
Defer Arel attribute lookup to the model class
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/join_dependency/join_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader/association.rb2
-rw-r--r--activerecord/lib/active_record/core.rb5
-rw-r--r--activerecord/lib/active_record/inheritance.rb2
-rw-r--r--activerecord/lib/active_record/relation.rb12
-rw-r--r--activerecord/lib/active_record/relation/batches.rb6
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb12
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb4
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb2
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb12
-rw-r--r--activerecord/lib/active_record/table_metadata.rb6
-rw-r--r--activerecord/test/cases/relation/mutation_test.rb4
12 files changed, 38 insertions, 31 deletions
diff --git a/activerecord/lib/active_record/associations/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/join_dependency/join_association.rb
index be65cf318c..708b3af5bd 100644
--- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb
+++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb
@@ -75,7 +75,7 @@ module ActiveRecord
column = klass.columns_hash[reflection.type.to_s]
binds << Relation::QueryAttribute.new(column.name, value, klass.type_for_attribute(column.name))
- constraint = constraint.and table[reflection.type].eq(Arel::Nodes::BindParam.new)
+ constraint = constraint.and klass.arel_attribute(reflection.type, table).eq(Arel::Nodes::BindParam.new)
end
joins << table.create_join(table, table.create_on(constraint), join_type)
diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb
index e11a5cfb8a..3032bc786e 100644
--- a/activerecord/lib/active_record/associations/preloader/association.rb
+++ b/activerecord/lib/active_record/associations/preloader/association.rb
@@ -47,7 +47,7 @@ module ActiveRecord
# This is overridden by HABTM as the condition should be on the foreign_key column in
# the join table
def association_key
- table[association_key_name]
+ klass.arel_attribute(association_key_name, table)
end
# The name of the key on the model which declares the association
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 475a298467..24fd0aaecf 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -256,6 +256,11 @@ module ActiveRecord
end
end
+ def arel_attribute(name, table = arel_table) # :nodoc:
+ name = attribute_alias(name) if attribute_alias?(name)
+ table[name]
+ end
+
def predicate_builder # :nodoc:
@predicate_builder ||= PredicateBuilder.new(table_metadata)
end
diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb
index 3b6fb70d0d..899683ee4f 100644
--- a/activerecord/lib/active_record/inheritance.rb
+++ b/activerecord/lib/active_record/inheritance.rb
@@ -192,7 +192,7 @@ module ActiveRecord
end
def type_condition(table = arel_table)
- sti_column = table[inheritance_column]
+ sti_column = arel_attribute(inheritance_column, table)
sti_names = ([self] + descendants).map(&:sti_name)
sti_column.in(sti_names)
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 032b8d4c5d..7e842668c6 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -47,7 +47,7 @@ module ActiveRecord
if !primary_key_value && connection.prefetch_primary_key?(klass.table_name)
primary_key_value = connection.next_sequence_value(klass.sequence_name)
- values[klass.arel_table[klass.primary_key]] = primary_key_value
+ values[arel_attribute(klass.primary_key)] = primary_key_value
end
end
@@ -105,6 +105,10 @@ module ActiveRecord
[substitutes, binds]
end
+ def arel_attribute(name) # :nodoc:
+ klass.arel_attribute(name, table)
+ end
+
# Initializes new record from relation while maintaining the current
# scope.
#
@@ -373,9 +377,9 @@ module ActiveRecord
stmt.table(table)
if joins_values.any?
- @klass.connection.join_to_update(stmt, arel, table[primary_key])
+ @klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
else
- stmt.key = table[primary_key]
+ stmt.key = arel_attribute(primary_key)
stmt.take(arel.limit)
stmt.order(*arel.orders)
stmt.wheres = arel.constraints
@@ -527,7 +531,7 @@ module ActiveRecord
stmt.from(table)
if joins_values.any?
- @klass.connection.join_to_delete(stmt, arel, table[primary_key])
+ @klass.connection.join_to_delete(stmt, arel, arel_attribute(primary_key))
else
stmt.wheres = arel.constraints
end
diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb
index 54587ae18e..de005e2810 100644
--- a/activerecord/lib/active_record/relation/batches.rb
+++ b/activerecord/lib/active_record/relation/batches.rb
@@ -204,15 +204,15 @@ module ActiveRecord
yield yielded_relation
break if ids.length < of
- batch_relation = relation.where(table[primary_key].gt(primary_key_offset))
+ batch_relation = relation.where(arel_attribute(primary_key).gt(primary_key_offset))
end
end
private
def apply_limits(relation, start, finish)
- relation = relation.where(table[primary_key].gteq(start)) if start
- relation = relation.where(table[primary_key].lteq(finish)) if finish
+ relation = relation.where(arel_attribute(primary_key).gteq(start)) if start
+ relation = relation.where(arel_attribute(primary_key).lteq(finish)) if finish
relation
end
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index f45844a9ea..54c9af4898 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -155,15 +155,7 @@ module ActiveRecord
# See also #ids.
#
def pluck(*column_names)
- column_names.map! do |column_name|
- if column_name.is_a?(Symbol) && attribute_alias?(column_name)
- attribute_alias(column_name)
- else
- column_name.to_s
- end
- end
-
- if loaded? && (column_names - @klass.column_names).empty?
+ if loaded? && (column_names.map(&:to_s) - @klass.attribute_names - @klass.attribute_aliases.keys).empty?
return @records.pluck(*column_names)
end
@@ -172,7 +164,7 @@ module ActiveRecord
else
relation = spawn
relation.select_values = column_names.map { |cn|
- columns_hash.key?(cn) ? arel_table[cn] : cn
+ @klass.has_attribute?(cn) || @klass.attribute_alias?(cn) ? arel_attribute(cn) : cn
}
result = klass.connection.select_all(relation.arel, nil, bound_attributes)
result.cast_values(klass.attribute_types)
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 3f5d6de78a..d48bcea28a 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -147,7 +147,7 @@ module ActiveRecord
def last(limit = nil)
if limit
if order_values.empty? && primary_key
- order(arel_table[primary_key].desc).limit(limit).reverse
+ order(arel_attribute(primary_key).desc).limit(limit).reverse
else
to_a.last(limit)
end
@@ -514,7 +514,7 @@ module ActiveRecord
# TODO: once the offset argument is removed from find_nth,
# find_nth_with_limit_and_offset can be merged into this method
relation = if order_values.empty? && primary_key
- order(arel_table[primary_key].asc)
+ order(arel_attribute(primary_key).asc)
else
self
end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb
index 063150958a..8a910a82fe 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/relation_handler.rb
@@ -3,7 +3,7 @@ module ActiveRecord
class RelationHandler # :nodoc:
def call(attribute, value)
if value.select_values.empty?
- value = value.select(value.klass.arel_table[value.klass.primary_key])
+ value = value.select(value.arel_attribute(value.klass.primary_key))
end
attribute.in(value.arel)
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 8ef9f9f627..91bfa4d131 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -1093,8 +1093,8 @@ module ActiveRecord
def arel_columns(columns)
columns.map do |field|
- if (Symbol === field || String === field) && columns_hash.key?(field.to_s) && !from_clause.value
- arel_table[field]
+ if (Symbol === field || String === field) && (klass.has_attribute?(field) || klass.attribute_alias?(field)) && !from_clause.value
+ arel_attribute(field)
elsif Symbol === field
connection.quote_table_name(field.to_s)
else
@@ -1105,7 +1105,7 @@ module ActiveRecord
def reverse_sql_order(order_query)
if order_query.empty?
- return [table[primary_key].desc] if primary_key
+ return [arel_attribute(primary_key).desc] if primary_key
raise IrreversibleOrderError,
"Relation has no current order and table has no primary key to be used as default order"
end
@@ -1170,12 +1170,10 @@ module ActiveRecord
order_args.map! do |arg|
case arg
when Symbol
- arg = klass.attribute_alias(arg) if klass.attribute_alias?(arg)
- table[arg].asc
+ arel_attribute(arg).asc
when Hash
arg.map { |field, dir|
- field = klass.attribute_alias(field) if klass.attribute_alias?(field)
- table[field].send(dir.downcase)
+ arel_attribute(field).send(dir.downcase)
}
else
arg
diff --git a/activerecord/lib/active_record/table_metadata.rb b/activerecord/lib/active_record/table_metadata.rb
index f9bb1cf5e0..0faad48ce3 100644
--- a/activerecord/lib/active_record/table_metadata.rb
+++ b/activerecord/lib/active_record/table_metadata.rb
@@ -22,7 +22,11 @@ module ActiveRecord
end
def arel_attribute(column_name)
- arel_table[column_name]
+ if klass
+ klass.arel_attribute(column_name, arel_table)
+ else
+ arel_table[column_name]
+ end
end
def type(column_name)
diff --git a/activerecord/test/cases/relation/mutation_test.rb b/activerecord/test/cases/relation/mutation_test.rb
index d0f60a84b5..ffb2da7a26 100644
--- a/activerecord/test/cases/relation/mutation_test.rb
+++ b/activerecord/test/cases/relation/mutation_test.rb
@@ -26,6 +26,10 @@ module ActiveRecord
def sanitize_sql_for_order(sql)
sql
end
+
+ def arel_attribute(name, table)
+ table[name]
+ end
end
def relation