aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/aggregations.rb3
-rw-r--r--activerecord/lib/active_record/associations.rb12
-rw-r--r--activerecord/lib/active_record/associations/association.rb2
-rw-r--r--activerecord/lib/active_record/associations/association_scope.rb2
-rw-r--r--activerecord/lib/active_record/associations/builder/association.rb22
-rw-r--r--activerecord/lib/active_record/associations/builder/singular_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/join_dependency/join_association.rb4
-rw-r--r--activerecord/lib/active_record/associations/join_helper.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader.rb2
-rw-r--r--activerecord/lib/active_record/autosave_association.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb25
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb5
-rw-r--r--activerecord/lib/active_record/core.rb2
-rw-r--r--activerecord/lib/active_record/locking/optimistic.rb2
-rw-r--r--activerecord/lib/active_record/model_schema.rb2
-rw-r--r--activerecord/lib/active_record/reflection.rb69
-rw-r--r--activerecord/lib/active_record/relation/delegation.rb20
-rw-r--r--activerecord/lib/active_record/relation/merger.rb2
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb8
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb2
-rw-r--r--activerecord/lib/active_record/result.rb28
-rw-r--r--activerecord/lib/active_record/sanitization.rb4
24 files changed, 140 insertions, 96 deletions
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb
index 9d1c12ec62..d075edc159 100644
--- a/activerecord/lib/active_record/aggregations.rb
+++ b/activerecord/lib/active_record/aggregations.rb
@@ -223,7 +223,8 @@ module ActiveRecord
reader_method(name, class_name, mapping, allow_nil, constructor)
writer_method(name, class_name, mapping, allow_nil, converter)
- create_reflection(:composed_of, part_id, nil, options, self)
+ reflection = ActiveRecord::Reflection.create(:composed_of, part_id, nil, options, self)
+ Reflection.add_reflection self, part_id, reflection
end
private
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 6fd4f3042c..5ceda933f2 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1205,7 +1205,8 @@ module ActiveRecord
# has_many :reports, -> { readonly }
# has_many :subscribers, through: :subscriptions, source: :user
def has_many(name, scope = nil, options = {}, &extension)
- Builder::HasMany.build(self, name, scope, options, &extension)
+ reflection = Builder::HasMany.build(self, name, scope, options, &extension)
+ Reflection.add_reflection self, name, reflection
end
# Specifies a one-to-one association with another class. This method should only be used
@@ -1308,7 +1309,8 @@ module ActiveRecord
# has_one :club, through: :membership
# has_one :primary_address, -> { where primary: true }, through: :addressables, source: :addressable
def has_one(name, scope = nil, options = {})
- Builder::HasOne.build(self, name, scope, options)
+ reflection = Builder::HasOne.build(self, name, scope, options)
+ Reflection.add_reflection self, name, reflection
end
# Specifies a one-to-one association with another class. This method should only be used
@@ -1420,7 +1422,8 @@ module ActiveRecord
# belongs_to :company, touch: true
# belongs_to :company, touch: :employees_last_updated_at
def belongs_to(name, scope = nil, options = {})
- Builder::BelongsTo.build(self, name, scope, options)
+ reflection = Builder::BelongsTo.build(self, name, scope, options)
+ Reflection.add_reflection self, name, reflection
end
# Specifies a many-to-many relationship with another class. This associates two classes via an
@@ -1557,7 +1560,8 @@ module ActiveRecord
# has_and_belongs_to_many :categories, join_table: "prods_cats"
# has_and_belongs_to_many :categories, -> { readonly }
def has_and_belongs_to_many(name, scope = nil, options = {}, &extension)
- Builder::HasAndBelongsToMany.build(self, name, scope, options, &extension)
+ reflection = Builder::HasAndBelongsToMany.build(self, name, scope, options, &extension)
+ Reflection.add_reflection self, name, reflection
end
end
end
diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb
index 338d5d2afe..67d24b35d1 100644
--- a/activerecord/lib/active_record/associations/association.rb
+++ b/activerecord/lib/active_record/associations/association.rb
@@ -117,7 +117,7 @@ module ActiveRecord
# Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
# through association's scope)
def target_scope
- AssociationRelation.new(klass, klass.arel_table, self).merge!(klass.all)
+ AssociationRelation.create(klass, klass.arel_table, self).merge!(klass.all)
end
# Loads the \target if needed and returns it.
diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb
index f1bec5787a..bdfafa5066 100644
--- a/activerecord/lib/active_record/associations/association_scope.rb
+++ b/activerecord/lib/active_record/associations/association_scope.rb
@@ -119,7 +119,7 @@ module ActiveRecord
# the owner
klass.table_name
else
- reflection.table_name
+ super
end
end
diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb
index bbc1c20f60..6b6a088806 100644
--- a/activerecord/lib/active_record/associations/builder/association.rb
+++ b/activerecord/lib/active_record/associations/builder/association.rb
@@ -2,7 +2,7 @@
# used by all associations.
#
# The hierarchy is defined as follows:
-# Association
+# Association
# - SingularAssociation
# - BelongsToAssociation
# - HasOneAssociation
@@ -14,11 +14,13 @@ module ActiveRecord::Associations::Builder
class Association #:nodoc:
class << self
attr_accessor :valid_options
+ attr_accessor :extensions
end
self.valid_options = [:class_name, :foreign_key, :validate]
+ self.extensions = []
- attr_reader :model, :name, :scope, :options, :reflection
+ attr_reader :model, :name, :scope, :options
def self.build(*args, &block)
new(*args, &block).build
@@ -48,15 +50,15 @@ module ActiveRecord::Associations::Builder
@model.generated_feature_methods
end
- include Module.new { def build; end }
-
def build
validate_options
define_accessors
configure_dependency if options[:dependent]
- @reflection = model.create_reflection(macro, name, scope, options, model)
- super # provides an extension point
- @reflection
+ reflection = ActiveRecord::Reflection.create(macro, name, scope, options, model)
+ Association.extensions.each do |extension|
+ extension.build @model, reflection
+ end
+ reflection
end
def macro
@@ -64,18 +66,18 @@ module ActiveRecord::Associations::Builder
end
def valid_options
- Association.valid_options
+ Association.valid_options + Association.extensions.flat_map(&:valid_options)
end
def validate_options
options.assert_valid_keys(valid_options)
end
-
+
# Defines the setter and getter methods for the association
# class Post < ActiveRecord::Base
# has_many :comments
# end
- #
+ #
# Post.first.comments and Post.first.comments= methods are defined by this method...
def define_accessors
diff --git a/activerecord/lib/active_record/associations/builder/singular_association.rb b/activerecord/lib/active_record/associations/builder/singular_association.rb
index 76e48e66e5..7bd894d6ab 100644
--- a/activerecord/lib/active_record/associations/builder/singular_association.rb
+++ b/activerecord/lib/active_record/associations/builder/singular_association.rb
@@ -16,7 +16,7 @@ module ActiveRecord::Associations::Builder
end
# Defines the (build|create)_association methods for belongs_to or has_one association
-
+
def define_constructors
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
def build_#{name}(*args, &block)
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 6ddbd4955d..b4047b08bc 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -34,7 +34,7 @@ module ActiveRecord
reload
end
- @proxy ||= CollectionProxy.new(klass, self)
+ @proxy ||= CollectionProxy.create(klass, self)
end
# Implements the writer method, e.g. foo.items= for Foo.has_many :items
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 8c528af399..58fc00d811 100644
--- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb
+++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb
@@ -105,13 +105,13 @@ module ActiveRecord
if item.is_a?(Relation)
item
else
- ActiveRecord::Relation.new(klass, table).instance_exec(self, &item)
+ ActiveRecord::Relation.create(klass, table).instance_exec(self, &item)
end
end
if reflection.type
scope_chain_items <<
- ActiveRecord::Relation.new(klass, table)
+ ActiveRecord::Relation.create(klass, table)
.where(reflection.type => foreign_klass.base_class.name)
end
diff --git a/activerecord/lib/active_record/associations/join_helper.rb b/activerecord/lib/active_record/associations/join_helper.rb
index 5a41b40c8f..27b70edf1a 100644
--- a/activerecord/lib/active_record/associations/join_helper.rb
+++ b/activerecord/lib/active_record/associations/join_helper.rb
@@ -19,7 +19,7 @@ module ActiveRecord
if reflection.source_macro == :has_and_belongs_to_many
tables << alias_tracker.aliased_table_for(
- (reflection.source_reflection || reflection).join_table,
+ reflection.source_reflection.join_table,
table_alias_for(reflection, true)
)
end
diff --git a/activerecord/lib/active_record/associations/preloader.rb b/activerecord/lib/active_record/associations/preloader.rb
index 82bf426b22..2317e34bc0 100644
--- a/activerecord/lib/active_record/associations/preloader.rb
+++ b/activerecord/lib/active_record/associations/preloader.rb
@@ -85,7 +85,7 @@ module ActiveRecord
def initialize(records, associations, preload_scope = nil)
@records = Array.wrap(records).compact.uniq
@associations = Array.wrap(associations)
- @preload_scope = preload_scope || Relation.new(nil, nil)
+ @preload_scope = preload_scope || Relation.create(nil, nil)
end
def run
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index c991c870ed..b30d1eb0a6 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -127,17 +127,17 @@ module ActiveRecord
extend ActiveSupport::Concern
module AssociationBuilderExtension #:nodoc:
- def build
+ def self.build(model, reflection)
model.send(:add_autosave_association_callbacks, reflection)
- super
+ end
+
+ def self.valid_options
+ [ :autosave ]
end
end
included do
- Associations::Builder::Association.class_eval do
- self.valid_options << :autosave
- include AssociationBuilderExtension
- end
+ Associations::Builder::Association.extensions << AssociationBuilderExtension
end
module ClassMethods
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 811749c7fd..cfdcae7f63 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -624,7 +624,7 @@ module ActiveRecord
end
response
- rescue
+ rescue Exception
ActiveRecord::Base.clear_active_connections! unless testing
raise
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index c64b542286..97e1bc5379 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -18,8 +18,7 @@ module ActiveRecord
end
end
- # Returns an array of record hashes with the column names as keys and
- # column values as values.
+ # Returns an ActiveRecord::Result instance.
def select_all(arel, name = nil, binds = [])
select(to_sql(arel, binds), name, binds)
end
@@ -27,8 +26,7 @@ module ActiveRecord
# Returns a record hash with the column names as keys and column values
# as values.
def select_one(arel, name = nil, binds = [])
- result = select_all(arel, name, binds)
- result.first if result
+ select_all(arel, name, binds).first
end
# Returns a single value from a record
@@ -355,8 +353,7 @@ module ActiveRecord
subselect
end
- # Returns an array of record hashes with the column names as keys and
- # column values as values.
+ # Returns an ActiveRecord::Result instance.
def select(sql, name = nil, binds = [])
end
undef_method :select
@@ -377,14 +374,14 @@ module ActiveRecord
update_sql(sql, name)
end
- def sql_for_insert(sql, pk, id_value, sequence_name, binds)
- [sql, binds]
- end
-
- def last_inserted_id(result)
- row = result.rows.first
- row && row.first
- end
+ def sql_for_insert(sql, pk, id_value, sequence_name, binds)
+ [sql, binds]
+ end
+
+ def last_inserted_id(result)
+ row = result.rows.first
+ row && row.first
+ end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index edeb338310..28c7cff1cc 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -1,6 +1,6 @@
require 'active_record/connection_adapters/abstract_mysql_adapter'
-gem 'mysql2', '~> 0.3.10'
+gem 'mysql2', '~> 0.3.13'
require 'mysql2'
module ActiveRecord
@@ -229,8 +229,7 @@ module ActiveRecord
alias exec_without_stmt exec_query
- # Returns an array of record hashes with the column names as keys and
- # column values as values.
+ # Returns an ActiveRecord::Result instance.
def select(sql, name = nil, binds = [])
exec_query(sql, name)
end
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index c6b7da2e3c..e088021112 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -146,7 +146,7 @@ module ActiveRecord
private
def relation #:nodoc:
- relation = Relation.new(self, arel_table)
+ relation = Relation.create(self, arel_table)
if finder_needs_type_condition?
relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb
index 2a7996c4e7..626fe40103 100644
--- a/activerecord/lib/active_record/locking/optimistic.rb
+++ b/activerecord/lib/active_record/locking/optimistic.rb
@@ -82,7 +82,7 @@ module ActiveRecord
stmt = relation.where(
relation.table[self.class.primary_key].eq(id).and(
- relation.table[lock_col].eq(self.class.quote_value(previous_lock_value))
+ relation.table[lock_col].eq(self.class.quote_value(previous_lock_value, column_for_attribute(lock_col)))
)
).arel.compile_update(arel_attributes_with_values_for_update(attribute_names))
diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb
index 44ea8610f2..23541d1d27 100644
--- a/activerecord/lib/active_record/model_schema.rb
+++ b/activerecord/lib/active_record/model_schema.rb
@@ -124,7 +124,7 @@ module ActiveRecord
@quoted_table_name = nil
@arel_table = nil
@sequence_name = nil unless defined?(@explicit_sequence_name) && @explicit_sequence_name
- @relation = Relation.new(self, arel_table)
+ @relation = Relation.create(self, arel_table)
end
# Returns a quoted version of the table name, used to construct SQL statements.
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 8a9488656b..73d154e03e 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -10,6 +10,27 @@ module ActiveRecord
self.aggregate_reflections = {}
end
+ def self.create(macro, name, scope, options, ar)
+ case macro
+ when :has_and_belongs_to_many
+ klass = AssociationReflection
+ when :has_many, :belongs_to, :has_one
+ klass = options[:through] ? ThroughReflection : AssociationReflection
+ when :composed_of
+ klass = AggregateReflection
+ end
+
+ klass.new(macro, name, scope, options, ar)
+ end
+
+ def self.add_reflection(ar, name, reflection)
+ if reflection.class == AggregateReflection
+ ar.aggregate_reflections = ar.aggregate_reflections.merge(name => reflection)
+ else
+ ar.reflections = ar.reflections.merge(name => reflection)
+ end
+ end
+
# \Reflection enables to interrogate Active Record classes and objects
# about their associations and aggregations. This information can,
# for example, be used in a form builder that takes an Active Record object
@@ -19,25 +40,6 @@ module ActiveRecord
# MacroReflection class has info for AggregateReflection and AssociationReflection
# classes.
module ClassMethods
- def create_reflection(macro, name, scope, options, active_record)
- case macro
- when :has_many, :belongs_to, :has_one, :has_and_belongs_to_many
- klass = options[:through] ? ThroughReflection : AssociationReflection
- when :composed_of
- klass = AggregateReflection
- end
-
- reflection = klass.new(macro, name, scope, options, active_record)
-
- if klass == AggregateReflection
- self.aggregate_reflections = self.aggregate_reflections.merge(name => reflection)
- else
- self.reflections = self.reflections.merge(name => reflection)
- end
-
- reflection
- end
-
# Returns an array of AggregateReflection objects for all the aggregations in the class.
def reflect_on_all_aggregations
aggregate_reflections.values
@@ -191,7 +193,7 @@ module ActiveRecord
attr_reader :type, :foreign_type
- def initialize(*args)
+ def initialize(macro, name, scope, options, active_record)
super
@collection = [:has_many, :has_and_belongs_to_many].include?(macro)
@automatic_inverse_of = nil
@@ -267,7 +269,7 @@ module ActiveRecord
end
def source_reflection
- nil
+ self
end
# A chain of reflections from this one back to the owner. For more see the explanation in
@@ -369,6 +371,12 @@ module ActiveRecord
VALID_AUTOMATIC_INVERSE_MACROS = [:has_many, :has_one, :belongs_to]
INVALID_AUTOMATIC_INVERSE_OPTIONS = [:conditions, :through, :polymorphic, :foreign_key]
+ protected
+
+ def actual_source_reflection # FIXME: this is a horrible name
+ self
+ end
+
private
# Attempts to find the inverse association name automatically.
# If it cannot find a suitable inverse association name, it returns
@@ -527,7 +535,9 @@ module ActiveRecord
#
def chain
@chain ||= begin
- chain = source_reflection.chain + through_reflection.chain
+ a = source_reflection.chain
+ b = through_reflection.chain
+ chain = a + b
chain[0] = self # Use self so we don't lose the information from :source_type
chain
end
@@ -578,7 +588,7 @@ module ActiveRecord
# A through association is nested if there would be more than one join table
def nested?
- chain.length > 2 || through_reflection.macro == :has_and_belongs_to_many
+ chain.length > 2 || through_reflection.has_and_belongs_to_many?
end
# We want to use the klass from this reflection, rather than just delegate straight to
@@ -587,12 +597,7 @@ module ActiveRecord
def association_primary_key(klass = nil)
# Get the "actual" source reflection if the immediate source reflection has a
# source reflection itself
- source_reflection = self.source_reflection
- while source_reflection.source_reflection
- source_reflection = source_reflection.source_reflection
- end
-
- source_reflection.options[:primary_key] || primary_key(klass || self.klass)
+ actual_source_reflection.options[:primary_key] || primary_key(klass || self.klass)
end
# Gets an array of possible <tt>:through</tt> source reflection names in both singular and plural form.
@@ -671,6 +676,12 @@ directive on your declaration like:
check_validity_of_inverse!
end
+ protected
+
+ def actual_source_reflection # FIXME: this is a horrible name
+ source_reflection.actual_source_reflection
+ end
+
private
def derive_class_name
# get the class_name of the belongs_to association of the through reflection
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index 8d6740246c..b6f80ac5c7 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -73,16 +73,8 @@ module ActiveRecord
module ClassMethods # :nodoc:
@@subclasses = ThreadSafe::Cache.new(:initial_capacity => 2)
- def new(klass, *args)
- relation = relation_class_for(klass).allocate
- relation.__send__(:initialize, klass, *args)
- relation
- end
-
- # This doesn't have to be thread-safe. relation_class_for guarantees that this will only be
- # called exactly once for a given const name.
- def const_missing(name)
- const_set(name, Class.new(self) { include ClassSpecificRelation })
+ def create(klass, *args)
+ relation_class_for(klass).new(klass, *args)
end
private
@@ -94,7 +86,13 @@ module ActiveRecord
# This hash is keyed by klass.name to avoid memory leaks in development mode
my_cache.compute_if_absent(klass_name) do
# Cache#compute_if_absent guarantees that the block will only executed once for the given klass_name
- const_get("#{name.gsub('::', '_')}_#{klass_name.gsub('::', '_')}", false)
+ subclass_name = "#{name.gsub('::', '_')}_#{klass_name.gsub('::', '_')}"
+
+ if const_defined?(subclass_name)
+ const_get(subclass_name)
+ else
+ const_set(subclass_name, Class.new(self) { include ClassSpecificRelation })
+ end
end
else
ActiveRecord::Relation
diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb
index da13152e01..c08158d38b 100644
--- a/activerecord/lib/active_record/relation/merger.rb
+++ b/activerecord/lib/active_record/relation/merger.rb
@@ -22,7 +22,7 @@ module ActiveRecord
# build a relation to merge in rather than directly merging
# the values.
def other
- other = Relation.new(relation.klass, relation.table)
+ other = Relation.create(relation.klass, relation.table)
hash.each { |k, v|
if k == :joins
if Hash === v
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index fb585ab8ab..d0c56ac3d0 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -100,6 +100,14 @@ module ActiveRecord
# firing an additional query. This will often result in a
# performance improvement over a simple +join+.
#
+ # You can also specify multiple relationships, like this:
+ #
+ # users = User.includes(:address, :friends)
+ #
+ # Loading nested relationships is possible using a Hash:
+ #
+ # users = User.includes(:address, friends: [:address, :followers])
+ #
# === conditions
#
# If you want to add conditions to your included models you'll have
diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb
index c63ae9c9fb..2552cbd234 100644
--- a/activerecord/lib/active_record/relation/spawn_methods.rb
+++ b/activerecord/lib/active_record/relation/spawn_methods.rb
@@ -64,7 +64,7 @@ module ActiveRecord
private
def relation_with(values) # :nodoc:
- result = Relation.new(klass, table, values)
+ result = Relation.create(klass, table, values)
result.extend(*extending_values) if extending_values.any?
result
end
diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb
index a7a035fe46..253368ae5b 100644
--- a/activerecord/lib/active_record/result.rb
+++ b/activerecord/lib/active_record/result.rb
@@ -3,8 +3,31 @@ module ActiveRecord
# This class encapsulates a Result returned from calling +exec_query+ on any
# database connection adapter. For example:
#
- # x = ActiveRecord::Base.connection.exec_query('SELECT * FROM foo')
- # x # => #<ActiveRecord::Result:0xdeadbeef>
+ # result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
+ # result # => #<ActiveRecord::Result:0xdeadbeef>
+ #
+ # # Get the column names of the result:
+ # result.columns
+ # # => ["id", "title", "body"]
+ #
+ # # Get the record values of the result:
+ # result.rows
+ # # => [[1, "title_1", "body_1"],
+ # [2, "title_2", "body_2"],
+ # ...
+ # ]
+ #
+ # # Get an array of hashes representing the result (column => value):
+ # result.to_hash
+ # # => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
+ # {"id" => 2, "title" => "title_2", "body" => "body_2"},
+ # ...
+ # ]
+ #
+ # # ActiveRecord::Result also includes Enumerable.
+ # result.each do |row|
+ # puts row['title'] + " " + row['body']
+ # end
class Result
include Enumerable
@@ -62,6 +85,7 @@ module ActiveRecord
end
private
+
def hash_rows
@hash_rows ||=
begin
diff --git a/activerecord/lib/active_record/sanitization.rb b/activerecord/lib/active_record/sanitization.rb
index 31e294022f..0b87ab9926 100644
--- a/activerecord/lib/active_record/sanitization.rb
+++ b/activerecord/lib/active_record/sanitization.rb
@@ -3,8 +3,8 @@ module ActiveRecord
extend ActiveSupport::Concern
module ClassMethods
- def quote_value(value, column = nil) #:nodoc:
- connection.quote(value,column)
+ def quote_value(value, column) #:nodoc:
+ connection.quote(value, column)
end
# Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to <tt>connection.quote</tt>.