Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added HasManyThroughWithoutDeletedAssociation so that has_many :thoug…

…h associations don't include deleted records by default.
  • Loading branch information...
commit 64e54fea5c8a780f16bc8c3d70b6974b4d915acb 1 parent a3fdbc0
Georg Friedrich georg authored
13 init.rb
View
@@ -11,6 +11,19 @@ def belongs_to_with_deleted(association_id, options = {})
end
end
+ def has_many_without_deleted(association_id, options = {}, &extension)
+ with_deleted = options.delete :with_deleted
+ returning has_many_with_deleted(association_id, options, &extension) do
+ if options[:through] && !with_deleted
+ reflection = reflect_on_association(association_id)
+ collection_reader_method(reflection, Caboose::Acts::HasManyThroughWithoutDeletedAssociation)
+ collection_accessor_methods(reflection, Caboose::Acts::HasManyThroughWithoutDeletedAssociation, false)
+ end
+ end
+ end
+
alias_method_chain :belongs_to, :deleted
+ alias_method :has_many_with_deleted, :has_many
+ alias_method :has_many, :has_many_without_deleted
end
ActiveRecord::Base.send :include, Caboose::Acts::Paranoid
27 lib/caboose/acts/has_many_through_without_deleted_association.rb
View
@@ -0,0 +1,27 @@
+module Caboose # :nodoc:
+ module Acts # :nodoc:
+ class HasManyThroughWithoutDeletedAssociation < ActiveRecord::Associations::HasManyThroughAssociation
+ protected
+ def current_time
+ ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
+ end
+
+ def construct_conditions
+ return super unless @reflection.through_reflection.klass.paranoid?
+ table_name = @reflection.through_reflection.table_name
+ conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value|
+ "#{table_name}.#{attr} = #{value}"
+ end
+
+ deleted_attribute = @reflection.through_reflection.klass.deleted_attribute
+ quoted_current_time = @reflection.through_reflection.klass.quote_value(
+ current_time,
+ @reflection.through_reflection.klass.columns_hash[deleted_attribute.to_s])
+ conditions << "#{table_name}.#{deleted_attribute} IS NULL OR #{table_name}.#{deleted_attribute} > #{quoted_current_time}"
+
+ conditions << sql_conditions if sql_conditions
+ "(" + conditions.join(') AND (') + ")"
+ end
+ end
+ end
+end
9 test/fixtures/taggings.yml
View
@@ -0,0 +1,9 @@
+tagging_1:
+ id: 1
+ tag_id: 1
+ widget_id: 1
+ deleted_at: '2005-01-01 00:00:00'
+tagging_2:
+ id: 2
+ tag_id: 2
+ widget_id: 1
6 test/fixtures/tags.yml
View
@@ -0,0 +1,6 @@
+tag_1:
+ id: 1
+ name: 'tag 1'
+tag_2:
+ id: 2
+ name: 'tag 1'
26 test/paranoid_test.rb
View
@@ -6,6 +6,9 @@ class Widget < ActiveRecord::Base
has_and_belongs_to_many :habtm_categories, :class_name => 'Category'
has_one :category
belongs_to :parent_category, :class_name => 'Category'
+ has_many :taggings
+ has_many :tags, :through => :taggings
+ has_many :any_tags, :through => :taggings, :class_name => 'Tag', :source => :tag, :with_deleted => true
end
class Category < ActiveRecord::Base
@@ -22,11 +25,22 @@ def self.search_with_deleted(name, options = {})
end
end
+class Tag < ActiveRecord::Base
+ has_many :taggings
+ has_many :widgets, :through => :taggings
+end
+
+class Tagging < ActiveRecord::Base
+ belongs_to :tag
+ belongs_to :widget
+ acts_as_paranoid
+end
+
class NonParanoidAndroid < ActiveRecord::Base
end
class ParanoidTest < Test::Unit::TestCase
- fixtures :widgets, :categories, :categories_widgets
+ fixtures :widgets, :categories, :categories_widgets, :tags, :taggings
def test_should_count_with_deleted
assert_equal 1, Widget.count
@@ -111,6 +125,16 @@ def test_should_not_find_deleted_habtm_associations
assert_equal [categories(:category_1)], widgets(:widget_1).habtm_categories
end
+ def test_should_not_find_deleted_has_many_through_associations
+ assert_equal 1, widgets(:widget_1).tags.size
+ assert_equal [tags(:tag_2)], widgets(:widget_1).tags
+ end
+
+ def test_should_find_has_many_through_associations_with_deleted
+ assert_equal 2, widgets(:widget_1).any_tags.size
+ assert_equal Tag.find(:all), widgets(:widget_1).any_tags
+ end
+
def test_should_not_find_deleted_belongs_to_associations
assert_nil Category.find_with_deleted(3).widget
end
10 test/schema.rb
View
@@ -16,5 +16,15 @@
t.column :category_id, :integer
t.column :widget_id, :integer
end
+
+ create_table :tags, :force => true do |t|
+ t.column :name, :string, :limit => 50
+ end
+
+ create_table :taggings, :force => true do |t|
+ t.column :tag_id, :integer
+ t.column :widget_id, :integer
+ t.column :deleted_at, :timestamp
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.