aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorEmilio Tagua <miloops@gmail.com>2009-08-18 14:10:03 -0300
committerEmilio Tagua <miloops@gmail.com>2009-08-18 14:10:03 -0300
commit66fbcc1de646129a3fc7415aa2f8416ef78d8cbb (patch)
tree58012f2b522159e34a6a751b2584e24f1d3ca05a /activerecord/lib
parentac03bc91dbee36233e061eb624f7781a49ab6fcf (diff)
downloadrails-66fbcc1de646129a3fc7415aa2f8416ef78d8cbb.tar.gz
rails-66fbcc1de646129a3fc7415aa2f8416ef78d8cbb.tar.bz2
rails-66fbcc1de646129a3fc7415aa2f8416ef78d8cbb.zip
Use immutable relation objects to generate queries.
Diffstat (limited to 'activerecord/lib')
-rwxr-xr-xactiverecord/lib/active_record/associations.rb37
-rwxr-xr-xactiverecord/lib/active_record/base.rb34
-rw-r--r--activerecord/lib/active_record/calculations.rb15
-rw-r--r--activerecord/lib/active_record/relation.rb71
4 files changed, 76 insertions, 81 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index d0322280d9..c0741bb572 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1682,14 +1682,14 @@ module ActiveRecord
relation = association.join_relation(relation)
end
- relation.joins!(construct_join(options[:joins], scope)).
- select!(column_aliases(join_dependency)).
- group!(construct_group(options[:group], options[:having], scope)).
- order!(construct_order(options[:order], scope)).
- conditions!(construct_conditions(options[:conditions], scope))
+ relation = relation.joins(construct_join(options[:joins], scope)).
+ select(column_aliases(join_dependency)).
+ group(construct_group(options[:group], options[:having], scope)).
+ order(construct_order(options[:order], scope)).
+ conditions(construct_conditions(options[:conditions], scope))
- relation.conditions!(construct_arel_limited_ids_condition(options, join_dependency)) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit])
- relation.limit!(construct_limit(options[:limit], scope)) if using_limitable_reflections?(join_dependency.reflections)
+ relation = relation.conditions(construct_arel_limited_ids_condition(options, join_dependency)) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit])
+ relation = relation.limit(construct_limit(options[:limit], scope)) if using_limitable_reflections?(join_dependency.reflections)
relation
end
@@ -1725,14 +1725,13 @@ module ActiveRecord
relation = association.join_relation(relation)
end
- relation.joins!(construct_join(options[:joins], scope)).
- conditions!(construct_conditions(options[:conditions], scope)).
- group!(construct_group(options[:group], options[:having], scope)).
- order!(construct_order(options[:order], scope)).
- limit!(construct_limit(options[:limit], scope)).
- offset!(construct_limit(options[:offset], scope))
-
- relation.select!(connection.distinct("#{connection.quote_table_name table_name}.#{primary_key}", construct_order(options[:order], scope(:find)).join(",")))
+ relation = relation.joins(construct_join(options[:joins], scope)).
+ conditions(construct_conditions(options[:conditions], scope)).
+ group(construct_group(options[:group], options[:having], scope)).
+ order(construct_order(options[:order], scope)).
+ limit(construct_limit(options[:limit], scope)).
+ offset(construct_limit(options[:offset], scope)).
+ select(connection.distinct("#{connection.quote_table_name table_name}.#{primary_key}", construct_order(options[:order], scope(:find)).join(",")))
sanitize_sql(relation.to_sql)
end
@@ -2222,12 +2221,12 @@ module ActiveRecord
def join_relation(joining_relation, join = nil)
if relation.is_a?(Array)
- joining_relation.joins!(relation.first, join_type).on!(association_join.first)
- joining_relation.joins!(relation.last, join_type).on!(association_join.last)
+ joining_relation.
+ joins(relation.first, join_type).on(association_join.first).
+ joins(relation.last, join_type).on(association_join.last)
else
- joining_relation.joins!(relation, join_type).on!(association_join)
+ joining_relation.joins(relation, join_type).on(association_join)
end
- joining_relation
end
protected
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 2b79788b89..b23ce53d43 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -869,15 +869,15 @@ module ActiveRecord #:nodoc:
relation = arel_table
if conditions = construct_conditions(conditions, scope)
- relation.conditions!(Arel::SqlLiteral.new(conditions))
+ relation = relation.conditions(Arel::SqlLiteral.new(conditions))
end
- if options.has_key?(:limit) || (scope && scope[:limit])
+ relation = if options.has_key?(:limit) || (scope && scope[:limit])
# Only take order from scope if limit is also provided by scope, this
# is useful for updating a has_many association with a limit.
- relation.order!(construct_order(options[:order], scope)).limit!(construct_limit(options[:limit], scope))
+ relation.order(construct_order(options[:order], scope)).limit(construct_limit(options[:limit], scope))
else
- relation.order!(options[:order])
+ relation.order(options[:order])
end
relation.update(sanitize_sql_for_assignment(updates))
@@ -932,7 +932,7 @@ module ActiveRecord #:nodoc:
# associations or call your <tt>before_*</tt> or +after_destroy+ callbacks, use the +destroy_all+ method instead.
def delete_all(conditions = nil)
if conditions
- arel_table.conditions!(Arel::SqlLiteral.new(construct_conditions(conditions, scope(:find)))).delete
+ arel_table.conditions(Arel::SqlLiteral.new(construct_conditions(conditions, scope(:find)))).delete
else
arel_table.delete
end
@@ -1535,7 +1535,7 @@ module ActiveRecord #:nodoc:
def arel_table(table = nil)
table = table_name if table.blank?
- Relation.new(self, table)
+ Relation.new(self, Arel::Table.new(table))
end
private
@@ -1720,13 +1720,13 @@ module ActiveRecord #:nodoc:
def construct_finder_arel(options = {}, scope = scope(:find))
# TODO add lock to Arel
relation = arel_table(options[:from]).
- joins!(construct_join(options[:joins], scope)).
- conditions!(construct_conditions(options[:conditions], scope)).
- select!(options[:select] || (scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))).
- group!(construct_group(options[:group], options[:having], scope)).
- order!(construct_order(options[:order], scope)).
- limit!(construct_limit(options[:limit], scope)).
- offset!(construct_offset(options[:offset], scope))
+ joins(construct_join(options[:joins], scope)).
+ conditions(construct_conditions(options[:conditions], scope)).
+ select(options[:select] || (scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))).
+ group(construct_group(options[:group], options[:having], scope)).
+ order(construct_order(options[:order], scope)).
+ limit(construct_limit(options[:limit], scope)).
+ offset(construct_offset(options[:offset], scope))
end
def construct_finder_sql(options, scope = scope(:find))
@@ -1810,7 +1810,7 @@ module ActiveRecord #:nodoc:
def build_association_joins(joins)
join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, joins, nil)
- relation = arel_table
+ relation = arel_table.relation
join_dependency.join_associations.map { |association|
if association.relation.is_a?(Array)
[Arel::InnerJoin.new(relation, association.relation.first, association.association_join.first).joins(relation),
@@ -2569,7 +2569,7 @@ module ActiveRecord #:nodoc:
# be made (since they can't be persisted).
def destroy
unless new_record?
- arel_table(true).conditions!(arel_table[self.class.primary_key].eq(id)).delete
+ arel_table(true).conditions(arel_table[self.class.primary_key].eq(id)).delete
end
@destroyed = true
@@ -2864,7 +2864,7 @@ module ActiveRecord #:nodoc:
def update(attribute_names = @attributes.keys)
attributes_with_values = arel_attributes_values(false, false, attribute_names)
return 0 if attributes_with_values.empty?
- arel_table(true).conditions!(arel_table[self.class.primary_key].eq(id)).update(attributes_with_values)
+ arel_table(true).conditions(arel_table[self.class.primary_key].eq(id)).update(attributes_with_values)
end
# Creates a record with values matching those of the instance attributes
@@ -2952,7 +2952,7 @@ module ActiveRecord #:nodoc:
end
def arel_table(reload = nil)
- @arel_table = Relation.new(self.class, self.class.table_name) if reload || @arel_table.nil?
+ @arel_table = Relation.new(self.class, Arel::Table.new(self.class.table_name)) if reload || @arel_table.nil?
@arel_table
end
diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb
index cd2fbe9b79..40242333e5 100644
--- a/activerecord/lib/active_record/calculations.rb
+++ b/activerecord/lib/active_record/calculations.rb
@@ -147,11 +147,11 @@ module ActiveRecord
construct_finder_arel_with_included_associations(options, join_dependency)
else
relation = arel_table(options[:from]).
- joins!(construct_join(options[:joins], scope)).
- conditions!(construct_conditions(options[:conditions], scope)).
- order!(options[:order]).
- limit!(options[:limit]).
- offset!(options[:offset])
+ joins(construct_join(options[:joins], scope)).
+ conditions(construct_conditions(options[:conditions], scope)).
+ order(options[:order]).
+ limit(options[:limit]).
+ offset(options[:offset])
end
if options[:group]
return execute_grouped_calculation(operation, column_name, options, relation)
@@ -171,7 +171,7 @@ module ActiveRecord
(column_name == :all ? "*" : column_name.to_s))
end
- relation.select!(operation == 'count' ? column.count(options[:distinct]) : column.send(operation))
+ relation = relation.select(operation == 'count' ? column.count(options[:distinct]) : column.send(operation))
type_cast_calculated_value(connection.select_value(relation.to_sql), column_for(column_name), operation)
end
@@ -194,8 +194,7 @@ module ActiveRecord
options[:select] << ", #{group_field} AS #{group_alias}"
- relation.select!(options[:select])
- relation.group!(construct_group(options[:group], options[:having], nil))
+ relation = relation.select(options[:select]).group(construct_group(options[:group], options[:having], nil))
calculated_data = connection.select_all(relation.to_sql)
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 9c7ba881fc..bba0d0844d 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -3,9 +3,9 @@ module ActiveRecord
delegate :to_sql, :to => :relation
attr_reader :relation, :klass
- def initialize(klass, table = nil)
+ def initialize(klass, relation)
@klass = klass
- @relation = Arel::Table.new(table || @klass.table_name)
+ @relation = relation
end
def to_a
@@ -21,60 +21,57 @@ module ActiveRecord
to_a.first
end
- def select!(selection)
- @relation = @relation.project(selection) if selection
- self
+ def select(selects)
+ Relation.new(@klass, @relation.project(selects))
end
- def on!(on)
- @relation = @relation.on(on) if on
- self
+ def group(groups)
+ Relation.new(@klass, @relation.group(groups))
end
- def order!(order)
- @relation = @relation.order(order) if order
- self
+ def order(orders)
+ Relation.new(@klass, @relation.order(orders))
end
- def group!(group)
- @relation = @relation.group(group) if group
- self
+ def limit(limits)
+ Relation.new(@klass, @relation.take(limits))
end
- def limit!(limit)
- @relation = @relation.take(limit) if limit
- self
+ def offset(offsets)
+ Relation.new(@klass, @relation.skip(offsets))
end
- def offset!(offset)
- @relation = @relation.skip(offset) if offset
- self
+ def on(join)
+ Relation.new(@klass, @relation.on(join))
end
- def joins!(joins, join_type = nil)
- if !joins.blank?
- @relation = case joins
- when String
- @relation.join(joins)
- when Hash, Array, Symbol
- if @klass.send(:array_of_strings?, joins)
- @relation.join(joins.join(' '))
+ def joins(join, join_type = nil)
+ if join.blank?
+ self
+ else
+ join = case join
+ when String
+ @relation.join(join)
+ when Hash, Array, Symbol
+ if @klass.send(:array_of_strings?, join)
+ @relation.join(join.join(' '))
+ else
+ @relation.join(@klass.send(:build_association_joins, join))
+ end
else
- @relation.join(@klass.send(:build_association_joins, joins))
- end
- else
- @relation.join(joins, join_type)
+ @relation.join(join, join_type)
end
+ Relation.new(@klass, join)
end
- self
end
- def conditions!(conditions)
- if !conditions.blank?
+ def conditions(conditions)
+ if conditions.blank?
+ self
+ else
conditions = @klass.send(:merge_conditions, conditions) if [String, Hash, Array].include?(conditions.class)
- @relation = @relation.where(conditions)
+ Relation.new(@klass, @relation.where(conditions))
end
- self
end
private