= requires_approval ===Installation To install, just add requires_approval to your Gemfile # Gemfile gem "requires_approval" === Activation To activate, use the requires_approval_for method in your class definition # app/models/user.rb # # - first_name :string # - last_name :string # - birthday :date # - created_at :datetime # - updated_at :datetime class User < ActiveRecord::Base requires_approval_for(:first_name, :last_name) end And create a migration that adds the necessary table and fields for your requires_approval model # db/migrate/TIMESTAMP_add_user_versions.rb def self.up User.prepare_tables_for_requires_approval end This does the equivalent of the the following # Generated migration def self.up create_table(:user_versions, :force => true) do |t| t.string(:first_name) t.string(:last_name) t.integer(:user_id) t.boolean(:is_approved) t.timestamps end add_index(:user_versions, [:user_id, :is_approved]) # starts all new records out as frozen so they don't show up add_column(:users, :is_frozen, :boolean, :default => true) end === Usage The first_name and last_name methods are now delegated to the user's latest_unapproved_version u = User.new u.first_name = "Dan" u.first_name => nil u.latest_unapproved_version.first_name => "Dan" u.pending_changes => { "first_name" => { "was" => nil, "became" => "Dan" } } u.save u.approve_attributes(:first_name) u.first_name => "Dan" # it created one version and approved it u.versions.count => 1 # so it won't show up as an unapproved version u.latest_unapproved_version => nil u.pending_changes => {} ==== Denying attributes You can also deny changes. If you do so, they just disappear from the latest_unapproved_version u = User.create(:first_name => "X", :last_name => "Y") u.approve_all_attributes u.update_attribute(:first_name => "Dan") u.pending_changes => { "first_name" => { "was" => "X", "became" => "Dan" } } u.deny_attributes(:first_name) # no more changes u.pending_changes => {} FYI, this doesn't actually remove the latest_unapproved_version, it just sets its values to be the same as the values in the parent record. == Contributing to requires_approval * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet. * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it. * Fork the project. * Start a feature/bugfix branch. * Commit and push until you are happy with your contribution. * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally. * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it. == Copyright Copyright (c) 2012 Dan Langevin. See LICENSE.txt for further details.