Gems required to run unit tests:
- redgreen
- assertions
What is this stupid app doing?
Foo has_many Bar – acts_as_paranoid test models
Xx has_many Yy – acts_as_archival test models
- It has an inconsistent interface
See tests in foo_test.rb
- It is not atomic.
see tests in foo_test.rb
aap – parnoid.rb
def recover! self.deleted_at = nil save! end def recover_with_associations!(*associations) self.recover! associations.to_a.each do |assoc| self.send(assoc).find_with_deleted(:all).each do |a| a.recover! if a.class.paranoid? end end end
- The code is pretty complicated
aap – paranoid_find_wrapper.rb
- It significantly messes with find, destroy, and delete.
This will screw you, immediately, or when it’s really important.
Additionally, everyone needs on your team needs to know how and why it’s screwing with these methods, or they will screw everyone.
- It is annoying – it lacks lots of helpers you would expect
f = Foo.first f.destroy f.recover! # ERRRORRRRROR, Wesley; you can't modify 'f' because it's now a locked hash. Foo.find_with_deleted(:all).first.recover! Foo.all_with_deleted doesn't exist #ERROR NoMethod Foo.first_with_deleted doesn't exist #ERROR NoMethod etc.
- It’s consistent
See xx_test
- It has a pretty limited interface, and doesn’t mess with active_record a great deal
See xx_test
marking a class as AAA adds 4 class methods and 3 instance methods, and 2 callbacks
Also, it doesn’t change any of the standard AR calls
- Atomic
You won’t unarchive associations unintentionally.
- Our documentation isn’t “Read the code”
Srsly, check out that README
- The code is still pretty complicated
acts_as_archival.rb
def act_on_all_archival_associations(head_archive_number, options={}) return if options.length == 0 options[:association_options] ||= Proc.new { true } self.class.reflect_on_all_associations.each do |association| if association.klass.is_archival? && association.macro.to_s =~ /^has/ && options[:association_options].call(association) act_on_a_related_archival(association.klass, association.primary_key_name, id, head_archive_number, options) end end end def act_on_a_related_archival(klass, key_name, id, head_archive_number, options={}) return if options.length == 0 || (!options[:archive] && !options[:unarchive]) if options[:archive] klass.unarchived.find(:all, :conditions => ["#{key_name} = ?", id]).each do |related_record| related_record.archive(head_archive_number) end else klass.archived.find(:all, :conditions => ["#{key_name} = ? AND archive_number = ?", id, head_archive_number]).each do |related_record| related_record.unarchive(head_archive_number) end end end