README.md
# protected_record [![Gem Version](https://badge.fury.io/rb/protected_record.png)](http://badge.fury.io/rb/protected_record)[![Build Status](https://travis-ci.org/rthbound/protected_record.png?branch=master)](https://travis-ci.org/rthbound/protected_record)[![Code Climate](https://codeclimate.com/github/rthbound/protected_record.png)](https://codeclimate.com/github/rthbound/protected_record)[![Coverage Status](https://coveralls.io/repos/github/rthbound/protected_record/badge.svg?branch=master)](https://coveralls.io/github/rthbound/protected_record?branch=master)
## Setup for rails applications
I've created a gem called [protected_record_manager](https://github.com/rthbound/protected_record_manager)
to provide the necessary migrations as well as a (very) basic interface
for triaging `ProtectedRecord::ChangeRequest::Record` objects.
You are free to use this gem without the engine, but you'll need to
[grab these](https://github.com/rthbound/protected_record_manager/tree/master/db/migrate).
### Your models
Prepare your models.
There's **two types** of models at play here:
* User (for now I expect a `User` class)
```ruby
# app/models/user.rb
include ProtectedRecord::ResponsibleUser
# includes ProtectedRecord::ChangeRequest::Changer
# & ProtectedRecord::ChangeLog::Changer
```
* Your records .. these are the models you want to track
```ruby
# app/models/some_record.rb
include ProtectedRecord::Record
# includes ProtectedRecord::ChangeRequest::Changeling
# & ProtectedRecord::ChangeLog::Changeling
```
#### Protected Keys
You have three options,
1. Inject the `:protected_keys` option when you execute the update
(this will always take precedence over option 2).
2. Include in your record class `ProtectedRecord::DirtyModel`
and define protected_keys there
```ruby
# How to define :protected_keys in your models.
class SomeRecord < ActiveRecord::Base
include ProtectedRecord::DirtyModel
protected_keys :do_not_resuscitate, :organ_donor
end
```
3. Your third option is to omit `:protected_keys` entirely.
If they are not specified using either method, ProtectedRecord will use an empty array.
## Usage & Function
1. protected_record will prevent changes to attributes you specify as protected.
2. Any attempted but prevented change will be logged as a
`ProtectedRecord::ChangeRequest::Record`.
3. If any changes are allowed through the filter, protected_record
will create a `ProtectedRecord::ChangeLog::Record` to log who changed what,
and for which record.
4. **Important!** ProtectedRecord is opt-in only. It does not change the
behavior of any AR methods, nor does it place any callbacks in your models.
In order to update with protection, use the following:
In the following example, the user will be allowed to change anything
except `:do_not_resuscitate`. Rejected changes will create
`ProtectedRecord::ChangeRequest::Record` objects. Permitted changes
will create `ProtectedRecord::ChangeLog::Record` objects.
```ruby
ready = ProtectedRecord::Update.new({
user: current_user,
params: record_params,
protected_record: @record,
protected_keys: %w{ do_not_resuscitate }
})
result = ready.execute!
result.successful? #=> true
```
and
```ruby
# What changed
@user.change_log_records
@some_record.change_log_records
# What changes were attempted
@user.change_request_records
@some_record.change_request_records
```
## Recent Changes
Okay, so not so recent. Rails 4 removed attr_accessible, which this gem was using.
The only change to the end user should be the need to whitelist any params using
[strong_parameters](https://github.com/rails/strong_parameters). Since this is technically
a breaking change, it's time to bump protected_record to v1.0.0.
## Contributing
Please do. There's plenty that could be done to round out both the interface
and the the feature set.
Issues and pull requests would be most appreciated.