lib/is_paranoid.rb in semanticart-is_paranoid-0.9.5 vs lib/is_paranoid.rb in semanticart-is_paranoid-0.9.6

- old
+ new

@@ -13,10 +13,14 @@ def is_paranoid opts = {} opts[:field] ||= [:deleted_at, Proc.new{Time.now.utc}, nil] class_inheritable_accessor :destroyed_field, :field_destroyed, :field_not_destroyed self.destroyed_field, self.field_destroyed, self.field_not_destroyed = opts[:field] + if self.reflect_on_all_associations.size > 0 && ! opts[:suppress_load_order_warning] + warn "is_paranoid warning in class #{self}: You should declare is_paranoid before your associations" + end + # This is the real magic. All calls made to this model will append # the conditions deleted_at => nil (or whatever your destroyed_field # and field_not_destroyed are). All exceptions require using # exclusive_scope (see self.delete_all, self.count_with_destroyed, # and self.find_with_destroyed defined in the module ClassMethods) @@ -25,9 +29,28 @@ extend ClassMethods include InstanceMethods end module ClassMethods + def is_or_equals_not_destroyed + if [nil, 'NULL'].include?(field_not_destroyed) + 'IS NULL' + else + "= #{field_not_destroyed}" + end + end + + # ensure that we respect the is_paranoid conditions when being loaded as a has_many :through + # NOTE: this only works if is_paranoid is declared before has_many relationships. + def has_many(association_id, options = {}, &extension) + if options.key?(:through) + conditions = "#{options[:through].to_s.pluralize}.#{destroyed_field} #{is_or_equals_not_destroyed}" + options[:conditions] = "(" + [options[:conditions], conditions].compact.join(") AND (") + ")" + end + super + end + + # Actually delete the model, bypassing the safety net. Because # this method is called internally by Model.delete(id) and on the # delete method in each instance, we don't need to specify those # methods separately def delete_all conditions = nil