aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2010-12-26 19:37:35 +0000
committerJon Leighton <j@jonathanleighton.com>2010-12-26 19:38:04 +0000
commitb0498372a10bda006350af42708a5588ab28ffcb (patch)
tree3dbbd2186cf61fa253d9302dd751c2f88b2636dc /activerecord/lib/active_record
parent0c272471fe815c121a83d959468b2f1b6f8aaba8 (diff)
downloadrails-b0498372a10bda006350af42708a5588ab28ffcb.tar.gz
rails-b0498372a10bda006350af42708a5588ab28ffcb.tar.bz2
rails-b0498372a10bda006350af42708a5588ab28ffcb.zip
Add a HasAssociation module for common code for has_* associations
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/associations.rb2
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb2
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb59
-rw-r--r--activerecord/lib/active_record/associations/has_association.rb54
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb3
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_one_through_association.rb4
-rw-r--r--activerecord/lib/active_record/associations/through_association.rb (renamed from activerecord/lib/active_record/associations/through_association_scope.rb)4
8 files changed, 69 insertions, 61 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 1056c51a3d..b49cf8de95 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -120,6 +120,8 @@ module ActiveRecord
# So there is no need to eager load them.
autoload :AssociationCollection, 'active_record/associations/association_collection'
autoload :AssociationProxy, 'active_record/associations/association_proxy'
+ autoload :HasAssociation, 'active_record/associations/has_association'
+ autoload :ThroughAssociation, 'active_record/associations/through_association'
autoload :BelongsToAssociation, 'active_record/associations/belongs_to_association'
autoload :BelongsToPolymorphicAssociation, 'active_record/associations/belongs_to_polymorphic_association'
autoload :HasAndBelongsToManyAssociation, 'active_record/associations/has_and_belongs_to_many_association'
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index c9f9c925b0..86cc17394c 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -18,6 +18,8 @@ module ActiveRecord
# If you need to work on all current children, new and existing records,
# +load_target+ and the +loaded+ flag are your friends.
class AssociationCollection < AssociationProxy #:nodoc:
+ include HasAssociation
+
delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped
def select(select = nil)
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index c7b171b41d..b60aa33c98 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -4,17 +4,17 @@ module ActiveRecord
module Associations
# = Active Record Associations
#
- # This is the root class of all association proxies:
+ # This is the root class of all association proxies ('+ Foo' signifies an included module Foo):
#
# AssociationProxy
# BelongsToAssociation
- # HasOneAssociation
# BelongsToPolymorphicAssociation
- # AssociationCollection
+ # AssociationCollection + HasAssociation
# HasAndBelongsToManyAssociation
# HasManyAssociation
- # HasManyThroughAssociation
- # HasOneThroughAssociation
+ # HasManyThroughAssociation + ThroughAssociation
+ # HasOneAssociation + HasAssociation
+ # HasOneThroughAssociation + ThroughAssociation
#
# Association proxies in Active Record are middlemen between the object that
# holds the association, known as the <tt>@owner</tt>, and the actual associated
@@ -176,43 +176,6 @@ module ActiveRecord
@reflection.klass.send(:sanitize_sql, sql, table_name)
end
- # Sets the owner attributes on the given record
- # Note: does not really make sense for belongs_to associations, but this method is not
- # used by belongs_to
- def set_owner_attributes(record)
- if @owner.persisted?
- construct_owner_attributes.each { |key, value| record[key] = value }
- end
- end
-
- # Returns a has linking the owner to the association represented by the reflection
- def construct_owner_attributes(reflection = @reflection)
- attributes = {}
- if reflection.macro == :belongs_to
- attributes[reflection.association_primary_key] = @owner.send(reflection.primary_key_name)
- else
- attributes[reflection.primary_key_name] = @owner.send(reflection.active_record_primary_key)
-
- if reflection.options[:as]
- attributes["#{reflection.options[:as]}_type"] = @owner.class.base_class.name
- end
- end
- attributes
- end
-
- # Builds an array of arel nodes from the owner attributes hash
- def construct_owner_conditions(table = aliased_table, reflection = @reflection)
- construct_owner_attributes(reflection).map do |attr, value|
- table[attr].eq(value)
- end
- end
-
- def construct_conditions
- conditions = construct_owner_conditions
- conditions << Arel.sql(sql_conditions) if sql_conditions
- aliased_table.create_and(conditions)
- end
-
# Merges into +options+ the ones coming from the reflection.
def merge_options_from_reflection!(options)
options.reverse_merge!(
@@ -312,18 +275,6 @@ module ActiveRecord
end
end
- if RUBY_VERSION < '1.9.2'
- # Array#flatten has problems with recursive arrays before Ruby 1.9.2.
- # Going one level deeper solves the majority of the problems.
- def flatten_deeper(array)
- array.collect { |element| (element.respond_to?(:flatten) && !element.is_a?(Hash)) ? element.flatten : element }.flatten
- end
- else
- def flatten_deeper(array)
- array.flatten
- end
- end
-
# Returns the ID of the owner, quoted if needed.
def owner_quoted_id
@owner.quoted_id
diff --git a/activerecord/lib/active_record/associations/has_association.rb b/activerecord/lib/active_record/associations/has_association.rb
new file mode 100644
index 0000000000..4407e2ea9a
--- /dev/null
+++ b/activerecord/lib/active_record/associations/has_association.rb
@@ -0,0 +1,54 @@
+module ActiveRecord
+ module Associations
+ # Included in all has_* associations (i.e. everything except belongs_to)
+ module HasAssociation #:nodoc:
+ protected
+ # Sets the owner attributes on the given record
+ def set_owner_attributes(record)
+ if @owner.persisted?
+ construct_owner_attributes.each { |key, value| record[key] = value }
+ end
+ end
+
+ # Returns a hash linking the owner to the association represented by the reflection
+ def construct_owner_attributes(reflection = @reflection)
+ attributes = {}
+ if reflection.macro == :belongs_to
+ attributes[reflection.association_primary_key] = @owner.send(reflection.primary_key_name)
+ else
+ attributes[reflection.primary_key_name] = @owner.send(reflection.active_record_primary_key)
+
+ if reflection.options[:as]
+ attributes["#{reflection.options[:as]}_type"] = @owner.class.base_class.name
+ end
+ end
+ attributes
+ end
+
+ # Builds an array of arel nodes from the owner attributes hash
+ def construct_owner_conditions(table = aliased_table, reflection = @reflection)
+ construct_owner_attributes(reflection).map do |attr, value|
+ table[attr].eq(value)
+ end
+ end
+
+ def construct_conditions
+ conditions = construct_owner_conditions
+ conditions << Arel.sql(sql_conditions) if sql_conditions
+ aliased_table.create_and(conditions)
+ end
+
+ if RUBY_VERSION < '1.9.2'
+ # Array#flatten has problems with recursive arrays before Ruby 1.9.2.
+ # Going one level deeper solves the majority of the problems.
+ def flatten_deeper(array)
+ array.collect { |element| (element.respond_to?(:flatten) && !element.is_a?(Hash)) ? element.flatten : element }.flatten
+ end
+ else
+ def flatten_deeper(array)
+ array.flatten
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index 4dabfe2ea3..8569a2f004 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -1,11 +1,10 @@
-require "active_record/associations/through_association_scope"
require 'active_support/core_ext/object/blank'
module ActiveRecord
# = Active Record Has Many Through Association
module Associations
class HasManyThroughAssociation < HasManyAssociation #:nodoc:
- include ThroughAssociationScope
+ include ThroughAssociation
alias_method :new, :build
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 654157d998..ca0828ea7b 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -2,6 +2,8 @@ module ActiveRecord
# = Active Record Belongs To Has One Association
module Associations
class HasOneAssociation < AssociationProxy #:nodoc:
+ include HasAssociation
+
def create(attrs = {}, replace_existing = true)
new_record(replace_existing) do |reflection|
attrs = merge_with_conditions(attrs)
diff --git a/activerecord/lib/active_record/associations/has_one_through_association.rb b/activerecord/lib/active_record/associations/has_one_through_association.rb
index 8c8c9fbe5d..c9ae930e93 100644
--- a/activerecord/lib/active_record/associations/has_one_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_through_association.rb
@@ -1,10 +1,8 @@
-require "active_record/associations/through_association_scope"
-
module ActiveRecord
# = Active Record Has One Through Association
module Associations
class HasOneThroughAssociation < HasOneAssociation
- include ThroughAssociationScope
+ include ThroughAssociation
def replace(new_value)
create_through_record(new_value)
diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association.rb
index 1abeb178ff..57718285f8 100644
--- a/activerecord/lib/active_record/associations/through_association_scope.rb
+++ b/activerecord/lib/active_record/associations/through_association.rb
@@ -1,7 +1,7 @@
module ActiveRecord
- # = Active Record Through Association Scope
+ # = Active Record Through Association
module Associations
- module ThroughAssociationScope
+ module ThroughAssociation
def scoped
with_scope(@scope) do