AJAX Tabs (Rails redux)

Posted by acts_as_flinn Sun, 25 Feb 2007 09:12:00 GMT

A while back I wrote a tutorial on AJAX Tabs as a plug for a PHP clone of Ruby on Rails called Biscuit. Well Biscuit is long gone, but the I still use the tutorial code, but just in Rails. So I came up with an update using Rails. Check out the Ruby on Rails AJAX Tabs Tutorial.

eCommerce on Rails @ Feb PhillyOnRails

Posted by acts_as_flinn Sun, 25 Feb 2007 03:59:00 GMT

Credit Card Processing with ActiveMerchant

So for anyone interested in Rails based eCommerce I’ll be presenting on the subject at PhillyOnRails this Monday February 26th, at Drexel. I’ll be presenting on Credit Card Processing with ActiveMerchant. So anyone keeping up will know that I’m psyched about the fact that ActiveMerchant 1.0.0 was just released.

Secure Database Storage with Sentry

I’m also going to try to cover Secure Database Storage with Sentry if I have time. This is a controversial subject for eCommerce because you’re not supposed to store certain types of information related to a transaction (for example CVV). Sentry makes asymmetric encryption a cinch. That means you can take super secret information along with an order or transaction and encrypt it for later retrieval by the merchant. All the merchant needs to do to access the secret is provide his private key similar to PGP/GPG or SSH. This beats the heck out of a lot of eCommerce methods.

The very popular PHP based osCommerce production code actually stores full credit card information in the database if you aren’t using a gateway. Of course newer beta versions don’t store the card number in database, but they email them unsecured to the merchant. That sucks.

So you might be saying “who doesn’t use a gateway?” Merchants that don’t ship products automatically or will make order adjustments, or have some other special after order process that has to be manually handled.

acts_as_paranoid_versioned or acts_as_versioned + acts_as_paranoid

Posted by acts_as_flinn Thu, 15 Feb 2007 07:04:00 GMT

I know what you are thinking, and yes this is the best title I could come up with: acts_as_paranoid_versioned does the trick.

A question to the PhillyOnRails mailing list prompted me to get around to this one.

acts_as_versioned and acts_as_paranoid are two really great plugins that make enterprisey|auditable|accountable rails based projects much easier.

acts_as_versioned stores changes made to records in a separate table for historic purposed, think wiki entries, order processing, cms pages, inventory, etc.

acts_as_paranoid overrides the destroy and finder methods in order to “delete” object but keep data around in the database. This is perfect for wiki entries, order processing, cms pages, inventory, etc.

Problem

Unfortunately using both plugins causes version records to be destroyed even though the base model keep the record around (setting deleted_at).

The problem with using them both lies in acts_as_versioned’s implementation. acts_as_versioned dynamically creates a versioned class then adds has_many in your base model. The plugin naturally relies on rails to handle cleanup for an object with :dependent => :delete_all. I say naturally because you really wouldn’t want old versions of a destroyed object hanging around… unless of course you did want old versions of a destroyed object hanging around.

“I want to use both acts_as_versioned and acts_as_paranoid to create an audit trail!”

So here’s the fix…

Code

Add this to config/environment.rb


module ActiveRecord
  module Acts
    module Versioned
      module ClassMethods
        def acts_as_paranoid_versioned
          acts_as_paranoid
          acts_as_versioned      

          # protect the versioned model
          self.versioned_class.class_eval do
            def self.delete_all(conditions = nil); return; end
          end
        end
      end
    end
  end
end

Then instead of calling both acts_as_versioned and acts_as_paranoid call acts_as_paranoid_versioned in your model.


class Example < ActiveRecord::Base
  acts_as_paranoid_versioned
end

Have your cake and eat it too

“Yay, it works!”

With this setup, the versioned record doesn’t pick up deleted_at. If you want to do that or add any other special functionality, change

def self.delete_all(conditions = nil); return; end

to


def self.delete_all(conditions = nil)
  # foo
end

Recommendations for acts_as_versioned

Make version_association_options available to override. At current, version_association_options gets set then class_eval puts it into action creating the callback for before_destroy. If version_association_options were placed outside the acts_as_versioned class method (it’s own method or attr) it would be much easier to override the delete_all behavior. For example: self.version_association_options.delete(:dependent)

Older posts: 1 ... 15 16 17 18