From 0ee7331c35994e543df396548c5b455c00c96cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 00:48:56 -0300 Subject: Define the association extensions without need to have a builder instance --- .../active_record/associations/builder/association.rb | 12 ++++++------ .../associations/builder/collection_association.rb | 16 ++++++++-------- activerecord/test/cases/associations/extension_test.rb | 3 +-- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index fe8274e1d8..3f63326b16 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -21,15 +21,15 @@ module ActiveRecord::Associations::Builder attr_reader :name, :scope, :options def self.build(model, name, scope, options, &block) - builder = create_builder model, name, scope, options, &block + extension = define_extensions model, name, &block + builder = create_builder model, name, scope, options, extension reflection = builder.build(model) define_accessors model, reflection define_callbacks model, reflection - builder.define_extensions model reflection end - def self.create_builder(model, name, scope, options, &block) + def self.create_builder(model, name, scope, options, extension = nil) raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol) if scope.is_a?(Hash) @@ -37,10 +37,10 @@ module ActiveRecord::Associations::Builder scope = nil end - new(name, scope, options, &block) + new(name, scope, options, extension) end - def initialize(name, scope, options) + def initialize(name, scope, options, extension) @name = name @scope = scope @options = options @@ -68,7 +68,7 @@ module ActiveRecord::Associations::Builder options.assert_valid_keys(valid_options) end - def define_extensions(model) + def self.define_extensions(model, name) end def self.define_callbacks(model, reflection) diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index d68f5d6792..70548bd277 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -14,12 +14,11 @@ module ActiveRecord::Associations::Builder attr_reader :block_extension - def initialize(name, scope, options) + def initialize(name, scope, options, extension) super - @mod = nil - if block_given? - @mod = Module.new(&Proc.new) - @scope = wrap_scope @scope, @mod + + if extension + @scope = wrap_scope @scope, extension end end @@ -32,10 +31,11 @@ module ActiveRecord::Associations::Builder } end - def define_extensions(model) - if @mod + def self.define_extensions(model, name) + if block_given? extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension" - model.parent.const_set(extension_module_name, @mod) + extension = Module.new(&Proc.new) + model.parent.const_set(extension_module_name, extension) end end diff --git a/activerecord/test/cases/associations/extension_test.rb b/activerecord/test/cases/associations/extension_test.rb index 47dff7d0ea..f8f2832ab1 100644 --- a/activerecord/test/cases/associations/extension_test.rb +++ b/activerecord/test/cases/associations/extension_test.rb @@ -75,7 +75,6 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase private def extend!(model) - builder = ActiveRecord::Associations::Builder::HasMany.new(:association_name, nil, {}) { } - builder.define_extensions(model) + ActiveRecord::Associations::Builder::HasMany.define_extensions(model, :association_name) { } end end -- cgit v1.2.3 From b83f3645c0e2a962720942f54bc258531632593e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 20:10:21 -0300 Subject: Make valid_options a class method --- activerecord/lib/active_record/associations/builder/association.rb | 4 ++-- activerecord/lib/active_record/associations/builder/belongs_to.rb | 2 +- .../lib/active_record/associations/builder/collection_association.rb | 2 +- activerecord/lib/active_record/associations/builder/has_many.rb | 2 +- activerecord/lib/active_record/associations/builder/has_one.rb | 2 +- .../lib/active_record/associations/builder/singular_association.rb | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index 3f63326b16..d5fd9d7aa6 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -60,12 +60,12 @@ module ActiveRecord::Associations::Builder raise NotImplementedError end - def valid_options + def self.valid_options(options) VALID_OPTIONS + Association.extensions.flat_map(&:valid_options) end def validate_options - options.assert_valid_keys(valid_options) + options.assert_valid_keys(self.class.valid_options(options)) end def self.define_extensions(model, name) diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index c0b1847f33..38034f6bc6 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -4,7 +4,7 @@ module ActiveRecord::Associations::Builder :belongs_to end - def valid_options + def self.valid_options(options) super + [:foreign_type, :polymorphic, :touch] end diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index 70548bd277..c8b1873531 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -7,7 +7,7 @@ module ActiveRecord::Associations::Builder CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove] - def valid_options + def self.valid_options(options) super + [:table_name, :before_add, :after_add, :before_remove, :after_remove, :extend] end diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb index 7909b93622..bdbbb61ada 100644 --- a/activerecord/lib/active_record/associations/builder/has_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_many.rb @@ -4,7 +4,7 @@ module ActiveRecord::Associations::Builder :has_many end - def valid_options + def self.valid_options(options) super + [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :counter_cache] end diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb index f359efd496..49940d5f2e 100644 --- a/activerecord/lib/active_record/associations/builder/has_one.rb +++ b/activerecord/lib/active_record/associations/builder/has_one.rb @@ -4,7 +4,7 @@ module ActiveRecord::Associations::Builder :has_one end - def valid_options + def self.valid_options(options) valid = super + [:order, :as] valid += [:through, :source, :source_type] if options[:through] valid diff --git a/activerecord/lib/active_record/associations/builder/singular_association.rb b/activerecord/lib/active_record/associations/builder/singular_association.rb index 9a25980be8..2a4b1c441f 100644 --- a/activerecord/lib/active_record/associations/builder/singular_association.rb +++ b/activerecord/lib/active_record/associations/builder/singular_association.rb @@ -2,7 +2,7 @@ module ActiveRecord::Associations::Builder class SingularAssociation < Association #:nodoc: - def valid_options + def self.valid_options(options) super + [:remote, :dependent, :counter_cache, :primary_key, :inverse_of] end -- cgit v1.2.3 From 3c27b6ee7e34a3ee2e73c3e77f7a13c60b53c3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 20:15:00 -0300 Subject: Make validate_options a class method --- activerecord/lib/active_record/associations/builder/association.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index d5fd9d7aa6..c731d3a080 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -45,7 +45,7 @@ module ActiveRecord::Associations::Builder @scope = scope @options = options - validate_options + self.class.validate_options(options) if scope && scope.arity == 0 @scope = proc { instance_exec(&scope) } @@ -64,8 +64,8 @@ module ActiveRecord::Associations::Builder VALID_OPTIONS + Association.extensions.flat_map(&:valid_options) end - def validate_options - options.assert_valid_keys(self.class.valid_options(options)) + def self.validate_options(options) + options.assert_valid_keys(valid_options(options)) end def self.define_extensions(model, name) -- cgit v1.2.3 From a929d78d7b4a1341c0ed538cdcce0b381f410a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 20:17:59 -0300 Subject: Move macro to class level --- activerecord/lib/active_record/associations/builder/association.rb | 4 ++-- activerecord/lib/active_record/associations/builder/belongs_to.rb | 2 +- activerecord/lib/active_record/associations/builder/has_many.rb | 2 +- activerecord/lib/active_record/associations/builder/has_one.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index c731d3a080..df9cc65758 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -53,10 +53,10 @@ module ActiveRecord::Associations::Builder end def build(model) - ActiveRecord::Reflection.create(macro, name, scope, options, model) + ActiveRecord::Reflection.create(self.class.macro, name, scope, options, model) end - def macro + def self.macro raise NotImplementedError end diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index 38034f6bc6..e5cf6576a5 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -1,6 +1,6 @@ module ActiveRecord::Associations::Builder class BelongsTo < SingularAssociation #:nodoc: - def macro + def self.macro :belongs_to end diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb index bdbbb61ada..227184cd19 100644 --- a/activerecord/lib/active_record/associations/builder/has_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_many.rb @@ -1,6 +1,6 @@ module ActiveRecord::Associations::Builder class HasMany < CollectionAssociation #:nodoc: - def macro + def self.macro :has_many end diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb index 49940d5f2e..2d9f012bc8 100644 --- a/activerecord/lib/active_record/associations/builder/has_one.rb +++ b/activerecord/lib/active_record/associations/builder/has_one.rb @@ -1,6 +1,6 @@ module ActiveRecord::Associations::Builder class HasOne < SingularAssociation #:nodoc: - def macro + def self.macro :has_one end -- cgit v1.2.3 From 19c36778822c09c6159c538478f296459f592687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 20:21:38 -0300 Subject: Move wrap_scope to class level --- .../lib/active_record/associations/builder/collection_association.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index c8b1873531..090e593358 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -18,7 +18,7 @@ module ActiveRecord::Associations::Builder super if extension - @scope = wrap_scope @scope, extension + @scope = self.class.wrap_scope @scope, extension end end @@ -80,7 +80,7 @@ module ActiveRecord::Associations::Builder private - def wrap_scope(scope, mod) + def self.wrap_scope(scope, mod) if scope proc { |owner| instance_exec(owner, &scope).extending(mod) } else -- cgit v1.2.3 From 1a30b1ed4066cbefc9faacae081655c1da38836f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 20:27:52 -0300 Subject: Remove unneeded reader --- .../lib/active_record/associations/builder/collection_association.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index 090e593358..2676037e80 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -12,8 +12,6 @@ module ActiveRecord::Associations::Builder :after_add, :before_remove, :after_remove, :extend] end - attr_reader :block_extension - def initialize(name, scope, options, extension) super -- cgit v1.2.3 From c1cd3424569cf76b0e19e2854ec2829d87ed02bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 20:48:28 -0300 Subject: Extract the scope building to a class method --- .../active_record/associations/builder/association.rb | 19 +++++++++++++++++-- .../associations/builder/collection_association.rb | 8 -------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index df9cc65758..4efd5aa8ba 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -42,14 +42,29 @@ module ActiveRecord::Associations::Builder def initialize(name, scope, options, extension) @name = name - @scope = scope @options = options self.class.validate_options(options) + @scope = self.class.build_scope(scope, extension) + end + + def self.build_scope(scope, extension) + new_scope = scope + if scope && scope.arity == 0 - @scope = proc { instance_exec(&scope) } + new_scope = proc { instance_exec(&scope) } + end + + if extension + new_scope = wrap_scope new_scope, extension end + + new_scope + end + + def self.wrap_scope(scope, extension) + scope end def build(model) diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index 2676037e80..521597e822 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -12,14 +12,6 @@ module ActiveRecord::Associations::Builder :after_add, :before_remove, :after_remove, :extend] end - def initialize(name, scope, options, extension) - super - - if extension - @scope = self.class.wrap_scope @scope, extension - end - end - def self.define_callbacks(model, reflection) super name = reflection.name -- cgit v1.2.3 From d0163e99d9affeccb341e12cc7c50b599f129b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 20:56:05 -0300 Subject: Remove builder instances All the job can be done at class level so we can avoid some object allocation --- .../associations/builder/association.rb | 22 +++++----------------- .../builder/has_and_belongs_to_many.rb | 10 +++++----- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index 4efd5aa8ba..023afef3b9 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -18,18 +18,15 @@ module ActiveRecord::Associations::Builder VALID_OPTIONS = [:class_name, :class, :foreign_key, :validate] - attr_reader :name, :scope, :options - def self.build(model, name, scope, options, &block) extension = define_extensions model, name, &block - builder = create_builder model, name, scope, options, extension - reflection = builder.build(model) + reflection = create_reflection model, name, scope, options, extension define_accessors model, reflection define_callbacks model, reflection reflection end - def self.create_builder(model, name, scope, options, extension = nil) + def self.create_reflection(model, name, scope, options, extension = nil) raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol) if scope.is_a?(Hash) @@ -37,16 +34,11 @@ module ActiveRecord::Associations::Builder scope = nil end - new(name, scope, options, extension) - end - - def initialize(name, scope, options, extension) - @name = name - @options = options + validate_options(options) - self.class.validate_options(options) + scope = build_scope(scope, extension) - @scope = self.class.build_scope(scope, extension) + ActiveRecord::Reflection.create(macro, name, scope, options, model) end def self.build_scope(scope, extension) @@ -67,10 +59,6 @@ module ActiveRecord::Associations::Builder scope end - def build(model) - ActiveRecord::Reflection.create(self.class.macro, name, scope, options, model) - end - def self.macro raise NotImplementedError end diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb index af596a3a64..1c9c04b044 100644 --- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb @@ -84,11 +84,11 @@ module ActiveRecord::Associations::Builder middle_name = [lhs_model.name.downcase.pluralize, association_name].join('_').gsub(/::/, '_').to_sym middle_options = middle_options join_model - hm_builder = HasMany.create_builder(lhs_model, - middle_name, - nil, - middle_options) - hm_builder.build lhs_model + + HasMany.create_reflection(lhs_model, + middle_name, + nil, + middle_options) end private -- cgit v1.2.3 From 2a10a1efed4a6bc7db120d545a58d2f9ba28151a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 9 Oct 2013 20:59:15 -0300 Subject: Method visibility will not make difference here --- activerecord/lib/active_record/associations/builder/association.rb | 2 -- activerecord/lib/active_record/associations/builder/belongs_to.rb | 2 -- .../lib/active_record/associations/builder/collection_association.rb | 2 -- activerecord/lib/active_record/associations/builder/has_one.rb | 2 -- 4 files changed, 8 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index 023afef3b9..d8d68eb908 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -114,8 +114,6 @@ module ActiveRecord::Associations::Builder raise NotImplementedError end - private - def self.add_before_destroy_callbacks(model, reflection) unless valid_dependent_options.include? reflection.options[:dependent] raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{reflection.options[:dependent]}" diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index e5cf6576a5..aa43c34d86 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -23,8 +23,6 @@ module ActiveRecord::Associations::Builder add_counter_cache_methods mixin end - private - def self.add_counter_cache_methods(mixin) return if mixin.method_defined? :belongs_to_counter_cache_after_create diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index 521597e822..2ff67f904d 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -68,8 +68,6 @@ module ActiveRecord::Associations::Builder CODE end - private - def self.wrap_scope(scope, mod) if scope proc { |owner| instance_exec(owner, &scope).extending(mod) } diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb index 2d9f012bc8..064a3c8b51 100644 --- a/activerecord/lib/active_record/associations/builder/has_one.rb +++ b/activerecord/lib/active_record/associations/builder/has_one.rb @@ -14,8 +14,6 @@ module ActiveRecord::Associations::Builder [:destroy, :delete, :nullify, :restrict_with_error, :restrict_with_exception] end - private - def self.add_before_destroy_callbacks(model, reflection) super unless reflection.options[:through] end -- cgit v1.2.3