Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

use GeneratedFeatureMethods module for associations

  • Loading branch information...
commit 61bcc318c865289d215e8e19618b9414bd07d1e8 1 parent 9cdf33a
@joshsusser joshsusser authored
View
8 activerecord/lib/active_record/associations/builder/association.rb
@@ -6,7 +6,7 @@ class Association #:nodoc:
# Set by subclasses
class_attribute :macro
- attr_reader :model, :name, :options, :reflection, :mixin
+ attr_reader :model, :name, :options, :reflection
def self.build(model, name, options)
new(model, name, options).build
@@ -14,8 +14,10 @@ def self.build(model, name, options)
def initialize(model, name, options)
@model, @name, @options = model, name, options
- @mixin = Module.new
- @model.__send__(:include, @mixin)
+ end
+
+ def mixin
+ @model.generated_feature_methods
end
def build
View
12 activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
@@ -15,10 +15,14 @@ def build
def define_destroy_hook
name = self.name
- mixin.send(:define_method, :destroy_associations) do
- association(name).delete_all
- super()
- end
+ model.send(:include, Module.new {
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def destroy_associations
+ association(#{name.to_sym.inspect}).delete_all
+ super
+ end
+ RUBY
+ })
end
# TODO: These checks should probably be moved into the Reflection, and we should not be
View
6 activerecord/lib/active_record/attribute_methods.rb
@@ -8,12 +8,6 @@ module AttributeMethods #:nodoc:
include ActiveModel::AttributeMethods
module ClassMethods
- def inherited(child_class)
- # force creation + include before accessor method modules
- child_class.generated_attribute_methods
- super
- end
-
# Generates all the attribute related methods for columns in the database
# accessors, mutators and query methods.
def define_attribute_methods
View
14 activerecord/lib/active_record/base.rb
@@ -450,6 +450,20 @@ class << self # Class methods
:having, :create_with, :uniq, :to => :scoped
delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped
+ def inherited(child_class) #:nodoc:
+ # force attribute methods to be higher in inheritance hierarchy than other generated methods
+ child_class.generated_attribute_methods
+ child_class.generated_feature_methods
+ super
+ end
+
+ def generated_feature_methods
+ unless const_defined?(:GeneratedFeatureMethods, false)
+ include const_set(:GeneratedFeatureMethods, Module.new)
+ end
+ const_get(:GeneratedFeatureMethods)
+ end
+
# Executes a custom SQL query against your database and returns all the results. The results will
# be returned as an array with columns requested encapsulated as attributes of the model you call
# this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
View
22 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -77,7 +77,7 @@ class DeveloperWithCounterSQL < ActiveRecord::Base
class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
- :parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
+ :parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings
def setup_data_for_habtm_case
ActiveRecord::Base.connection.execute('delete from countries_treaties')
@@ -445,6 +445,26 @@ def test_destroy_all
assert david.projects(true).empty?
end
+ def test_destroy_associations_destroys_multiple_associations
+ george = parrots(:george)
+ assert !george.pirates.empty?
+ assert !george.treasures.empty?
+
+ assert_no_difference "Pirate.count" do
+ assert_no_difference "Treasure.count" do
+ george.destroy_associations
+ end
+ end
+
+ join_records = Parrot.connection.select_all("SELECT * FROM parrots_pirates WHERE parrot_id = #{george.id}")
+ assert join_records.empty?
+ assert george.pirates(true).empty?
+
+ join_records = Parrot.connection.select_all("SELECT * FROM parrots_treasures WHERE parrot_id = #{george.id}")
+ assert join_records.empty?
+ assert george.treasures(true).empty?
+ end
+
def test_deprecated_push_with_attributes_was_removed
jamis = developers(:jamis)
assert_raise(NoMethodError) do
View
9 activerecord/test/cases/base_test.rb
@@ -69,6 +69,15 @@ def setup
class BasicsTest < ActiveRecord::TestCase
fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts
+ def test_generated_methods_modules
+ modules = Computer.ancestors
+ assert modules.include?(Computer::GeneratedFeatureMethods)
+ assert_equal(Computer::GeneratedFeatureMethods, Computer.generated_feature_methods)
+ assert(modules.index(Computer.generated_attribute_methods) > modules.index(Computer.generated_feature_methods),
+ "generated_attribute_methods must be higher in inheritance hierarchy than generated_feature_methods")
+ assert_not_equal Computer.generated_feature_methods, Post.generated_feature_methods
+ end
+
def test_column_names_are_escaped
conn = ActiveRecord::Base.connection
classname = conn.class.name[/[^:]*$/]
View
1  activerecord/test/models/author.rb
@@ -128,7 +128,6 @@ def testing_proxy_target
belongs_to :author_address, :dependent => :destroy
belongs_to :author_address_extra, :dependent => :delete, :class_name => "AuthorAddress"
- has_many :post_categories, :through => :posts, :source => :categories
has_many :category_post_comments, :through => :categories, :source => :post_comments
has_many :misc_posts, :class_name => 'Post',
Please sign in to comment.
Something went wrong with that request. Please try again.