lukewendling / expressive_record
- Source
- Commits
- Network (0)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Branch:
master
expressive_record / README.rdoc
| 3b809e54 » | lukewendling | 2008-11-17 | 1 | == Expressive Record | |
| 2 | |||||
| c3725657 » | lukewendling | 2008-11-18 | 3 | Add meaningful names for belongs_to associations to Rails 2.1 model object dirty changes (http://dev.rubyonrails.org/changeset/9127) to help with rolling your own history/audit logger. | |
| 3b809e54 » | lukewendling | 2008-11-17 | 4 | ||
| 5 | == Install | ||||
| 6 | |||||
| 8d5c9de4 » | lukewendling | 2008-11-17 | 7 | script/plugin install git://github.com/lukewendling/expressive_record.git | |
| 8 | or | ||||
| 9 | sudo gem install lukewendling-expressive_record --source http://gems.github.com | ||||
| 10 | |||||
| c3725657 » | lukewendling | 2008-11-18 | 11 | create a migration for the audit table (see USAGE) | |
| 3b809e54 » | lukewendling | 2008-11-17 | 12 | ||
| 13 | == Usage | ||||
| 14 | |||||
| 15 | ActiveRecord 2.1 introduces dirty changes; the ability to query a model object to track attribute changes before the record is saved using #changes, #changed, etc. | ||||
| 16 | |||||
| c3725657 » | lukewendling | 2008-11-18 | 17 | However, belongs_to associations are cached simply as foreign key changes, so Ticket#changes yields something like {"status_id" => ["111", "222"]}, which isn't especially helpful when rolling your own audit logger. | |
| 3b809e54 » | lukewendling | 2008-11-17 | 18 | ||
| c3725657 » | lukewendling | 2008-11-18 | 19 | Expressive Record turns association (foreign key) changes into meaningful terms when the changes are saved to your audit table. | |
| 3b809e54 » | lukewendling | 2008-11-17 | 20 | ||
| 21 | class Ticket < ActiveRecord::Base | ||||
| 8d5c9de4 » | lukewendling | 2008-11-17 | 22 | include ExpressiveRecord | |
| 23 | |||||
| 24 | has_many :ticket_changes | ||||
| 3b809e54 » | lukewendling | 2008-11-17 | 25 | ||
| c3725657 » | lukewendling | 2008-11-18 | 26 | # pass in the name of your audit table (optional) | |
| 8d5c9de4 » | lukewendling | 2008-11-17 | 27 | express_changes :ticket_changes | |
| 3b809e54 » | lukewendling | 2008-11-17 | 28 | ||
| 29 | end | ||||
| 30 | |||||
| c3725657 » | lukewendling | 2008-11-18 | 31 | express_changes adds a before_update callback to your model that inserts changes into an audit table with the following schema: | |
| 3b809e54 » | lukewendling | 2008-11-17 | 32 | ||
| 33 | class CreateTicketChanges < ActiveRecord::Migration | ||||
| 34 | def self.up | ||||
| 35 | create_table "ticket_changes", :force => true do |t| | ||||
| 36 | t.integer "ticket_id", :null => false | ||||
| 37 | t.string "attribute_type", :null => false | ||||
| 38 | t.text "old_value" | ||||
| 39 | t.text "new_value" | ||||
| 40 | t.timestamps | ||||
| 41 | end | ||||
| 42 | end | ||||
| 8d5c9de4 » | lukewendling | 2008-11-17 | 43 | end | |
| 44 | |||||
| 906f577d » | lukewendling | 2008-11-24 | 45 | If using a before_update callback in subclasses, be sure to call 'super' as needed: | |
| 46 | |||||
| 47 | class A | ||||
| 48 | # a before_update callback is auto-magically added | ||||
| 49 | express_changes | ||||
| 50 | end | ||||
| 51 | |||||
| 52 | class A < B | ||||
| 53 | def before_update | ||||
| 54 | self.status = 'New' # do this before auditing | ||||
| 55 | super # now insert changes into audit log | ||||
| 56 | end | ||||
| 57 | end | ||||
| 58 | |||||
| c3725657 » | lukewendling | 2008-11-18 | 59 | == Limitations | |
| 60 | * the current implementation assumes that all belongs_to foreign keys use Rails conventional names, like user_id or status_id. if you are connecting to a legacy db with fk's like customerID or whatever, this won't work. | ||||
| 61 | |||||
| 8d5c9de4 » | lukewendling | 2008-11-17 | 62 | == TODO | |
| c3725657 » | lukewendling | 2008-11-18 | 63 | * add migration generator to create conventionally-named log table (i.e. ticket_changes) to schema | |
