aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2012-08-10 17:42:48 +0100
committerJon Leighton <j@jonathanleighton.com>2012-08-10 23:28:08 +0100
commit6e57d5c5840716b63851f02a6a806ba968065bca (patch)
tree241f62b761113c87ea03f81fa33373e8f5c74ac3
parent5b3bb61f3fb82c7300d4dac374fe7aeafff6bda0 (diff)
downloadrails-6e57d5c5840716b63851f02a6a806ba968065bca.tar.gz
rails-6e57d5c5840716b63851f02a6a806ba968065bca.tar.bz2
rails-6e57d5c5840716b63851f02a6a806ba968065bca.zip
Use method compilation for association methods
Method compilation provides better performance and I think the code comes out cleaner as well. A knock on effect is that methods that get redefined produce warnings. I think this is a good thing. I had to deal with a bunch of warnings coming from our tests, though.
-rw-r--r--activerecord/lib/active_record/associations/builder/association.rb27
-rw-r--r--activerecord/lib/active_record/associations/builder/belongs_to.rb57
-rw-r--r--activerecord/lib/active_record/associations/builder/collection_association.rb18
-rw-r--r--activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb2
-rw-r--r--activerecord/lib/active_record/associations/builder/singular_association.rb22
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/join_model_test.rb2
-rw-r--r--activerecord/test/cases/multiple_db_test.rb4
-rw-r--r--activerecord/test/cases/timestamp_test.rb28
-rw-r--r--activerecord/test/models/author.rb2
-rw-r--r--activerecord/test/models/member.rb5
-rw-r--r--activerecord/test/support/connection.rb4
12 files changed, 86 insertions, 89 deletions
diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb
index cae640648b..1df876bf62 100644
--- a/activerecord/lib/active_record/associations/builder/association.rb
+++ b/activerecord/lib/active_record/associations/builder/association.rb
@@ -63,17 +63,19 @@ module ActiveRecord::Associations::Builder
end
def define_readers
- name = self.name
- mixin.redefine_method(name) do |*params|
- association(name).reader(*params)
- end
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def #{name}(*args)
+ association(:#{name}).reader(*args)
+ end
+ CODE
end
def define_writers
- name = self.name
- mixin.redefine_method("#{name}=") do |value|
- association(name).writer(value)
- end
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def #{name}=(value)
+ association(:#{name}).writer(value)
+ end
+ CODE
end
def configure_dependency
@@ -88,10 +90,11 @@ module ActiveRecord::Associations::Builder
)
end
- name = self.name
- mixin.redefine_method("#{macro}_dependent_for_#{name}") do
- association(name).handle_dependency
- end
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def #{macro}_dependent_for_#{name}
+ association(:#{name}).handle_dependency
+ end
+ CODE
model.before_destroy "#{macro}_dependent_for_#{name}"
end
diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb
index acfc3073a9..2f2600b7fb 100644
--- a/activerecord/lib/active_record/associations/builder/belongs_to.rb
+++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb
@@ -21,49 +21,42 @@ module ActiveRecord::Associations::Builder
def add_counter_cache_callbacks(reflection)
cache_column = reflection.counter_cache_column
- name = self.name
- method_name = "belongs_to_counter_cache_after_create_for_#{name}"
- mixin.redefine_method(method_name) do
- record = send(name)
- record.class.increment_counter(cache_column, record.id) unless record.nil?
- end
- model.after_create(method_name)
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def belongs_to_counter_cache_after_create_for_#{name}
+ record = #{name}
+ record.class.increment_counter(:#{cache_column}, record.id) unless record.nil?
+ end
- method_name = "belongs_to_counter_cache_before_destroy_for_#{name}"
- mixin.redefine_method(method_name) do
- unless marked_for_destruction?
- record = send(name)
- record.class.decrement_counter(cache_column, record.id) unless record.nil?
+ def belongs_to_counter_cache_before_destroy_for_#{name}
+ unless marked_for_destruction?
+ record = #{name}
+ record.class.decrement_counter(:#{cache_column}, record.id) unless record.nil?
+ end
end
- end
- model.before_destroy(method_name)
+ CODE
- model.send(:module_eval,
- "#{reflection.class_name}.send(:attr_readonly,\"#{cache_column}\".intern) if defined?(#{reflection.class_name}) && #{reflection.class_name}.respond_to?(:attr_readonly)", __FILE__, __LINE__
- )
+ model.after_create "belongs_to_counter_cache_after_create_for_#{name}"
+ model.before_destroy "belongs_to_counter_cache_before_destroy_for_#{name}"
+
+ klass = reflection.class_name.safe_constantize
+ klass.attr_readonly cache_column if klass && klass.respond_to?(:attr_readonly)
end
def add_touch_callbacks(reflection)
- name = self.name
- method_name = "belongs_to_touch_after_save_or_destroy_for_#{name}"
- touch = options[:touch]
-
- mixin.redefine_method(method_name) do
- record = send(name)
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def belongs_to_touch_after_save_or_destroy_for_#{name}
+ record = #{name}
- unless record.nil?
- if touch == true
- record.touch
- else
- record.touch(touch)
+ unless record.nil?
+ record.touch #{options[:touch].inspect if options[:touch] != true}
end
end
- end
+ CODE
- model.after_save(method_name)
- model.after_touch(method_name)
- model.after_destroy(method_name)
+ model.after_save "belongs_to_touch_after_save_or_destroy_for_#{name}"
+ model.after_touch "belongs_to_touch_after_save_or_destroy_for_#{name}"
+ model.after_destroy "belongs_to_touch_after_save_or_destroy_for_#{name}"
end
def valid_dependent_options
diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb
index 40c13dae43..1b382f7285 100644
--- a/activerecord/lib/active_record/associations/builder/collection_association.rb
+++ b/activerecord/lib/active_record/associations/builder/collection_association.rb
@@ -65,19 +65,21 @@ module ActiveRecord::Associations::Builder
def define_readers
super
- name = self.name
- mixin.redefine_method("#{name.to_s.singularize}_ids") do
- association(name).ids_reader
- end
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def #{name.to_s.singularize}_ids
+ association(:#{name}).ids_reader
+ end
+ CODE
end
def define_writers
super
- name = self.name
- mixin.redefine_method("#{name.to_s.singularize}_ids=") do |ids|
- association(name).ids_writer(ids)
- end
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def #{name.to_s.singularize}_ids=(ids)
+ association(:#{name}).ids_writer(ids)
+ end
+ CODE
end
end
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 c2b53b9b2c..bdac02b5bf 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
@@ -29,7 +29,7 @@ module ActiveRecord::Associations::Builder
model.send(:include, Module.new {
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def destroy_associations
- association(#{name.to_sym.inspect}).delete_all
+ association(:#{name}).delete_all
super
end
RUBY
diff --git a/activerecord/lib/active_record/associations/builder/singular_association.rb b/activerecord/lib/active_record/associations/builder/singular_association.rb
index 0f96929a29..6a5830e57f 100644
--- a/activerecord/lib/active_record/associations/builder/singular_association.rb
+++ b/activerecord/lib/active_record/associations/builder/singular_association.rb
@@ -14,19 +14,19 @@ module ActiveRecord::Associations::Builder
end
def define_constructors
- name = self.name
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def build_#{name}(*args, &block)
+ association(:#{name}).build(*args, &block)
+ end
- mixin.redefine_method("build_#{name}") do |*params, &block|
- association(name).build(*params, &block)
- end
+ def create_#{name}(*args, &block)
+ association(:#{name}).create(*args, &block)
+ end
- mixin.redefine_method("create_#{name}") do |*params, &block|
- association(name).create(*params, &block)
- end
-
- mixin.redefine_method("create_#{name}!") do |*params, &block|
- association(name).create!(*params, &block)
- end
+ def create_#{name}!(*args, &block)
+ association(:#{name}).create!(*args, &block)
+ end
+ CODE
end
end
end
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index ec7e4f5fb7..5f7825783b 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -524,13 +524,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
def test_invalid_belongs_to_dependent_option_nullify_raises_exception
assert_raise ArgumentError do
- Author.belongs_to :special_author_address, :dependent => :nullify
+ Class.new(Author).belongs_to :special_author_address, :dependent => :nullify
end
end
def test_invalid_belongs_to_dependent_option_restrict_raises_exception
assert_raise ArgumentError do
- Author.belongs_to :special_author_address, :dependent => :restrict
+ Class.new(Author).belongs_to :special_author_address, :dependent => :restrict
end
end
diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb
index 3cea20527e..86893ec4b3 100644
--- a/activerecord/test/cases/associations/join_model_test.rb
+++ b/activerecord/test/cases/associations/join_model_test.rb
@@ -385,7 +385,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
end
def test_has_many_through_polymorphic_has_one
- assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).tagging
+ assert_equal Tagging.find(1,2).sort_by { |t| t.id }, authors(:david).taggings_2
end
def test_has_many_through_polymorphic_has_many
diff --git a/activerecord/test/cases/multiple_db_test.rb b/activerecord/test/cases/multiple_db_test.rb
index 06d6596725..42461e8ecb 100644
--- a/activerecord/test/cases/multiple_db_test.rb
+++ b/activerecord/test/cases/multiple_db_test.rb
@@ -1,9 +1,7 @@
require "cases/helper"
require 'models/entrant'
require 'models/bird'
-
-# So we can test whether Course.connection survives a reload.
-require_dependency 'models/course'
+require 'models/course'
class MultipleDbTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb
index 7444dc5de1..bb034848e1 100644
--- a/activerecord/test/cases/timestamp_test.rb
+++ b/activerecord/test/cases/timestamp_test.rb
@@ -114,9 +114,12 @@ class TimestampTest < ActiveRecord::TestCase
end
def test_saving_a_record_with_a_belongs_to_that_specifies_touching_a_specific_attribute_the_parent_should_update_that_attribute
- Pet.belongs_to :owner, :touch => :happy_at
+ klass = Class.new(ActiveRecord::Base) do
+ def self.name; 'Pet'; end
+ belongs_to :owner, :touch => :happy_at
+ end
- pet = Pet.first
+ pet = klass.first
owner = pet.owner
previously_owner_happy_at = owner.happy_at
@@ -124,14 +127,15 @@ class TimestampTest < ActiveRecord::TestCase
pet.save
assert_not_equal previously_owner_happy_at, pet.owner.happy_at
- ensure
- Pet.belongs_to :owner, :touch => true
end
def test_touching_a_record_with_a_belongs_to_that_uses_a_counter_cache_should_update_the_parent
- Pet.belongs_to :owner, :counter_cache => :use_count, :touch => true
+ klass = Class.new(ActiveRecord::Base) do
+ def self.name; 'Pet'; end
+ belongs_to :owner, :counter_cache => :use_count, :touch => true
+ end
- pet = Pet.first
+ pet = klass.first
owner = pet.owner
owner.update_columns(happy_at: 3.days.ago)
previously_owner_updated_at = owner.updated_at
@@ -140,15 +144,15 @@ class TimestampTest < ActiveRecord::TestCase
pet.save
assert_not_equal previously_owner_updated_at, pet.owner.updated_at
- ensure
- Pet.belongs_to :owner, :touch => true
end
def test_touching_a_record_touches_parent_record_and_grandparent_record
- Toy.belongs_to :pet, :touch => true
- Pet.belongs_to :owner, :touch => true
+ klass = Class.new(ActiveRecord::Base) do
+ def self.name; 'Toy'; end
+ belongs_to :pet, :touch => true
+ end
- toy = Toy.first
+ toy = klass.first
pet = toy.pet
owner = pet.owner
time = 3.days.ago
@@ -158,8 +162,6 @@ class TimestampTest < ActiveRecord::TestCase
owner.reload
assert_not_equal time, owner.updated_at
- ensure
- Toy.belongs_to :pet
end
def test_timestamp_attributes_for_create
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index 3157d8fe7f..77f4a2ec87 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -93,8 +93,8 @@ class Author < ActiveRecord::Base
has_many :author_favorites
has_many :favorite_authors, -> { order('name') }, :through => :author_favorites
- has_many :tagging, :through => :posts
has_many :taggings, :through => :posts
+ has_many :taggings_2, :through => :posts, :source => :tagging
has_many :tags, :through => :posts
has_many :post_categories, :through => :posts, :source => :categories
has_many :tagging_tags, :through => :taggings, :source => :tag
diff --git a/activerecord/test/models/member.rb b/activerecord/test/models/member.rb
index 359b29fac3..1134b09d8b 100644
--- a/activerecord/test/models/member.rb
+++ b/activerecord/test/models/member.rb
@@ -24,11 +24,10 @@ class Member < ActiveRecord::Base
has_one :club_category, :through => :club, :source => :category
- has_many :current_memberships
- has_one :club_through_many, :through => :current_memberships, :source => :club
-
has_many :current_memberships, -> { where :favourite => true }
has_many :clubs, :through => :current_memberships
+
+ has_one :club_through_many, :through => :current_memberships, :source => :club
end
class SelfMember < ActiveRecord::Base
diff --git a/activerecord/test/support/connection.rb b/activerecord/test/support/connection.rb
index c176316a05..92736e0ca9 100644
--- a/activerecord/test/support/connection.rb
+++ b/activerecord/test/support/connection.rb
@@ -1,6 +1,6 @@
require 'active_support/logger'
-require_dependency 'models/college'
-require_dependency 'models/course'
+require 'models/college'
+require 'models/course'
module ARTest
def self.connection_name