aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/associations.rb16
-rw-r--r--activerecord/lib/active_record/associations/association.rb6
-rw-r--r--activerecord/lib/active_record/associations/builder/association.rb21
-rw-r--r--activerecord/lib/active_record/associations/builder/collection_association.rb8
-rw-r--r--activerecord/lib/active_record/reflection.rb11
5 files changed, 37 insertions, 25 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index a62fce4756..a90c5a2a9a 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1192,8 +1192,8 @@ module ActiveRecord
# ORDER BY p.first_name
# }
# }
- def has_many(name, options = {}, &extension)
- Builder::HasMany.build(self, name, options, &extension)
+ def has_many(name, scope = {}, options = nil, &extension)
+ Builder::HasMany.build(self, name, scope, options, &extension)
end
# Specifies a one-to-one association with another class. This method should only be used
@@ -1308,8 +1308,8 @@ module ActiveRecord
# has_one :boss, :readonly => :true
# has_one :club, :through => :membership
# has_one :primary_address, :through => :addressables, :conditions => ["addressable.primary = ?", true], :source => :addressable
- def has_one(name, options = {})
- Builder::HasOne.build(self, name, options)
+ def has_one(name, scope = {}, options = nil)
+ Builder::HasOne.build(self, name, scope, options)
end
# Specifies a one-to-one association with another class. This method should only be used
@@ -1431,8 +1431,8 @@ module ActiveRecord
# belongs_to :post, :counter_cache => true
# belongs_to :company, :touch => true
# belongs_to :company, :touch => :employees_last_updated_at
- def belongs_to(name, options = {})
- Builder::BelongsTo.build(self, name, options)
+ def belongs_to(name, scope = {}, options = nil)
+ Builder::BelongsTo.build(self, name, scope, options)
end
# Specifies a many-to-many relationship with another class. This associates two classes via an
@@ -1605,8 +1605,8 @@ module ActiveRecord
# has_and_belongs_to_many :categories, :readonly => true
# has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql =>
# proc { |record| "DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}" }
- def has_and_belongs_to_many(name, options = {}, &extension)
- Builder::HasAndBelongsToMany.build(self, name, options, &extension)
+ def has_and_belongs_to_many(name, scope = {}, options = nil, &extension)
+ Builder::HasAndBelongsToMany.build(self, name, scope, options, &extension)
end
end
end
diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb
index e75003f261..624942d08a 100644
--- a/activerecord/lib/active_record/associations/association.rb
+++ b/activerecord/lib/active_record/associations/association.rb
@@ -82,7 +82,7 @@ module ActiveRecord
end
def scoped
- target_scope.merge(association_scope)
+ target_scope.merge(association_scope).merge(reflection_scope)
end
# The scope for this association.
@@ -101,6 +101,10 @@ module ActiveRecord
@association_scope = nil
end
+ def reflection_scope
+ reflection.scope && klass.instance_exec(&reflection.scope)
+ end
+
# Set the inverse association, if possible
def set_inverse_instance(record)
if record && invertible_for?(record)
diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb
index 9a6896dd55..f1a9f254b1 100644
--- a/activerecord/lib/active_record/associations/builder/association.rb
+++ b/activerecord/lib/active_record/associations/builder/association.rb
@@ -6,14 +6,23 @@ module ActiveRecord::Associations::Builder
# Set by subclasses
class_attribute :macro
- attr_reader :model, :name, :options, :reflection
+ attr_reader :model, :name, :scope, :options, :reflection
- def self.build(model, name, options)
- new(model, name, options).build
+ def self.build(*args, &block)
+ new(*args, &block).build
end
- def initialize(model, name, options)
- @model, @name, @options = model, name, options
+ def initialize(model, name, scope, options)
+ @model = model
+ @name = name
+
+ if options
+ @scope = scope
+ @options = options
+ else
+ @scope = nil
+ @options = scope
+ end
end
def mixin
@@ -22,7 +31,7 @@ module ActiveRecord::Associations::Builder
def build
validate_options
- reflection = model.create_reflection(self.class.macro, name, options, model)
+ reflection = model.create_reflection(self.class.macro, name, scope, options, model)
define_accessors
reflection
end
diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb
index 768f70b6c9..50836b496f 100644
--- a/activerecord/lib/active_record/associations/builder/collection_association.rb
+++ b/activerecord/lib/active_record/associations/builder/collection_association.rb
@@ -9,12 +9,8 @@ module ActiveRecord::Associations::Builder
attr_reader :block_extension
- def self.build(model, name, options, &extension)
- new(model, name, options, &extension).build
- end
-
- def initialize(model, name, options, &extension)
- super(model, name, options)
+ def initialize(*args, &extension)
+ super(*args)
@block_extension = extension
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 0d9534acd6..31c674e1c4 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -20,9 +20,9 @@ module ActiveRecord
# MacroReflection class has info for the AssociationReflection
# class.
module ClassMethods
- def create_reflection(macro, name, options, active_record)
+ def create_reflection(macro, name, scope, options, active_record)
klass = options[:through] ? ThroughReflection : AssociationReflection
- reflection = klass.new(macro, name, options, active_record)
+ reflection = klass.new(macro, name, scope, options, active_record)
self.reflections = self.reflections.merge(name => reflection)
reflection
@@ -71,6 +71,8 @@ module ActiveRecord
# <tt>has_many :clients</tt> returns <tt>:has_many</tt>
attr_reader :macro
+ attr_reader :scope
+
# Returns the hash of options used for the macro.
#
# <tt>has_many :clients</tt> returns +{}+
@@ -80,9 +82,10 @@ module ActiveRecord
attr_reader :plural_name # :nodoc:
- def initialize(macro, name, options, active_record)
+ def initialize(macro, name, scope, options, active_record)
@macro = macro
@name = name
+ @scope = scope
@options = options
@active_record = active_record
@plural_name = active_record.pluralize_table_names ?
@@ -142,7 +145,7 @@ module ActiveRecord
@klass ||= active_record.send(:compute_type, class_name)
end
- def initialize(macro, name, options, active_record)
+ def initialize(*args)
super
@collection = [:has_many, :has_and_belongs_to_many].include?(macro)
end