Skip to content

Commit

Permalink
Make sure habtm and has_one are safely used
Browse files Browse the repository at this point in the history
  • Loading branch information
Luca Guidi committed Oct 13, 2008
1 parent a514121 commit 5c01b60
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
@@ -1,3 +1,7 @@
* Make sure habtm and has_one are safely used



*0.0.2 (October 10th, 2008)*

* Updated README with new installation instructions
Expand Down
21 changes: 21 additions & 0 deletions lib/activerecord/lib/active_record/associations.rb
Expand Up @@ -306,6 +306,27 @@ def collection_reader_method(reflection, association_proxy_class, options)
end
end

def has_and_belongs_to_many(association_id, options = {}, &extension)
reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension)

add_multiple_associated_validation_callbacks(reflection.name) unless options[:validate] == false
add_multiple_associated_save_callbacks(reflection.name)
collection_accessor_methods(reflection, HasAndBelongsToManyAssociation, options)

# Don't use a before_destroy callback since users' before_destroy
# callbacks will be executed after the association is wiped out.
old_method = "destroy_without_habtm_shim_for_#{reflection.name}"
class_eval <<-end_eval unless method_defined?(old_method)
alias_method :#{old_method}, :destroy_without_callbacks
def destroy_without_callbacks
#{reflection.name}.clear
#{old_method}
end
end_eval

add_association_callbacks(reflection.name, options)
end

def collection_accessor_methods(reflection, association_proxy_class, options, writer = true)
collection_reader_method(reflection, association_proxy_class, options)

Expand Down
35 changes: 30 additions & 5 deletions tasks/cached_models_tasks.rake
Expand Up @@ -3,7 +3,7 @@ require 'active_record'
require 'active_record/fixtures'

path_to_fixtures = File.dirname(__FILE__) + '/../test/fixtures'
fixtures = %w( authors blogs posts comments tags )
fixtures = %w( addresses authors blogs posts categories categories_posts comments tags )

desc 'Run default task (test)'
task :cached_models => 'cached_models:test'
Expand All @@ -21,6 +21,17 @@ namespace :cached_models do
desc 'Create CachedModels test database tables'
task :create_tables => :environment do
ActiveRecord::Schema.define do
create_table :addresses, :force => true do |t|
t.integer :author_id
t.string :street
t.string :zip
t.string :city
t.string :state
t.string :country

t.timestamps
end

create_table :authors, :force => true do |t|
t.integer :blog_id
t.string :first_name
Expand All @@ -32,7 +43,7 @@ namespace :cached_models do

create_table :blogs, :force => true do |t|
t.string :title

t.timestamps
end

Expand All @@ -46,30 +57,44 @@ namespace :cached_models do
t.timestamps
end

create_table :categories, :force => true do |t|
t.string :name

t.timestamps
end

create_table :categories_posts, :force => true do |t|
t.integer :category_id
t.integer :post_id
end

create_table :comments, :force => true do |t|
t.integer :post_id
t.string :email
t.text :text

t.timestamps
end

create_table :tags, :force => true do |t|
t.integer :taggable_id
t.string :taggable_type
t.string :name

t.timestamps
end
end
end

desc 'Drops CachedModels test database tables'
task :drop_tables => :environment do
ActiveRecord::Base.connection.drop_table :addresses
ActiveRecord::Base.connection.drop_table :authors
ActiveRecord::Base.connection.drop_table :posts
ActiveRecord::Base.connection.drop_table :comments
ActiveRecord::Base.connection.drop_table :tags
ActiveRecord::Base.connection.drop_table :categories
ActiveRecord::Base.connection.drop_table :categories_posts
end

desc 'Load fixtures'
Expand Down
@@ -0,0 +1,12 @@
require File.dirname(__FILE__) + '/../../test_helper'

class HasAndBelongsToManyAssociationTest < Test::Unit::TestCase
include ActiveRecord::Associations

def test_should_not_raise_exception
assert_nothing_raised ArgumentError do
posts(:welcome).categories
categories(:announcements).posts
end
end
end
12 changes: 12 additions & 0 deletions test/active_record/associations/has_one_association_test.rb
@@ -0,0 +1,12 @@
require File.dirname(__FILE__) + '/../../test_helper'

class HasOneAssociationTest < Test::Unit::TestCase
include ActiveRecord::Associations

def test_should_not_raise_exception_when_use_has_one
assert_nothing_raised ArgumentError do
authors(:luca).address
addresses(:luca).author
end
end
end
7 changes: 7 additions & 0 deletions test/fixtures/addresses.yml
@@ -0,0 +1,7 @@
luca:
author_id: 1
street: 1 infinite loop
zip: 95014
city: Cupertino
state: California
country: United States
3 changes: 3 additions & 0 deletions test/fixtures/categories.yml
@@ -0,0 +1,3 @@
announcements:
id: 1
name: Announcements
3 changes: 3 additions & 0 deletions test/fixtures/categories_posts.yml
@@ -0,0 +1,3 @@
welcome_announcements:
category_id: 1
post_id: 1
3 changes: 3 additions & 0 deletions test/models/address.rb
@@ -0,0 +1,3 @@
class Address < ActiveRecord::Base
belongs_to :author
end
1 change: 1 addition & 0 deletions test/models/author.rb
Expand Up @@ -7,4 +7,5 @@ class Author < ActiveRecord::Base
has_many :cached_posts_with_comments, :class_name => 'Post', :include => :comments, :cached => true
has_many :comments, :through => :posts
has_many :cached_comments, :through => :posts, :source => :comments, :cached => true
has_one :address
end
3 changes: 3 additions & 0 deletions test/models/category.rb
@@ -0,0 +1,3 @@
class Category < ActiveRecord::Base
has_and_belongs_to_many :posts
end
1 change: 1 addition & 0 deletions test/models/post.rb
Expand Up @@ -4,4 +4,5 @@ class Post < ActiveRecord::Base
has_many :comments
has_many :tags, :as => :taggable
has_many :cached_tags, :as => :taggable, :class_name => 'Tag', :cached => true
has_and_belongs_to_many :categories
end

0 comments on commit 5c01b60

Please sign in to comment.