= UUIDs
{}[https://rubygems.org/gems/uuids]
{}[https://travis-ci.org/nepalez/uuids]
{}[https://codeclimate.com/github/nepalez/uuids]
{}[https://gemnasium.com/nepalez/uuids]
{}[https://coveralls.io/r/nepalez/uuids]
{}[https://github.com/nepalez/uuids/blob/master/LICENSE.rdoc]
== About
Defines a model +Uuid+ to store {UUIDs}[http://en.wikipedia.org/wiki/Universally_Unique_Identifier] assigned to various AR records.
It is expected any uuid is assigned to one record, but a record can be
identified by many uuids.
The gem is a {mountable Rails engine}[http://guides.rubyonrails.org/engines.html#generating-an-engine].
=== Pattern
This model allows refering records by some uuid (not the id).
If necessary any referred record can be merged with another one.
If you reassign all their uuids to merged record then any references remains
valid without tracking and changing them before merge.
A uuid should be neither deleted, no changed. It can only be reassigned to
another resource. The records can be deleted
* by merging to another ones;
* by explicitly marking as deleted without physical removal.
=== Example
Suppose you have models referred to cities. One day you discover
a duplication among cities: the "New York" and the "NEW YORK".
You should:
* reassign both uuids to "New York";
* safely remove the "NEW YORK" record.
You needn't track all records that refer to "NEW YORK". All those references
will authomatically lead to merged record via old uuid.
=== Standards
The Uuid is generated authomatically following the
{RFC4122}[http://www.ietf.org/rfc/rfc4122.txt] standard. The generation uses the
+sequrerandom+ Ruby library.
This allows keeping all uuids in one model and referring to any record whatever
type it has.
=== Models
A model Uuids::Uuid has two attributes: +value+ and +record+.
Only the +record+ can (and must) be set and changed.
The readonly +value+ (the uuid itself) is assigned by default.
=== Translations
Error messages are translated to English and Russian (see `config/locales`).
Translations to other languages are welcome.
== Installation
Add this line to your application's Gemfile:
gem "uuids"
And then execute:
$ bundle
Or install it yourself as:
$ gem install uuids
=== Rails application
Run from a command line in application root:
$ rake uuids:install
This will copy gem migrations to a `db/migrate` folder and run it.
=== Rails mountable engine
Run from a command line in application root:
$ rake app:uuids:install
This will copy gem migrations to a `spec/dummy/db/migrate` folder and run it.
== Usage
Add the assotiation to your AR model:
class YourModel < ActiveRecord::Base
# declares the association
has_many :uuids, class_name: "Uuids::Uuid", as: :record, dependent: :destroy
# auto-generates uuid by default
before_create -> { uuids.new }
# prevents the record from being unreferable
validates :uuids, presence: true, unless: :destroy
end
**Note** the dependent: :destroy condition! It requires all uuids
to be reassigned before destruction.
Now you can refer to your model via uuid:
class CreateAnotherModelTable < ActiveRecord::Migration
def change
create_table :another_models do |t|
t.string :your_model_uuid, limit: 36
end
add_index :another_models, :your_model_uuid
end
end
class AnotherModel < ActiveRecord::Base
def your_model
@your_model ||= YourModel.join(:uuids)
.where(uuids_uuids: { value: your_model_uuid }).first
end
def your_model=(record)
@your_model_uuid ||= Uuids::Uuid.find_by_record(record).try(:value)
end
end
== Uninstallation
=== Rails app
Run from a command line in application root:
$ rake uuids:uninstall
This will rollback and remove migration from `db/migrate` folder and then
remove the gem dependencies from application's +Gemfile+ and gemspec.
=== Rails mountable engine
Run from a command line in engine root:
$ rake app:uuids:uninstall
This will rollback and remove migration from `spec/dummy/db/migrate` folder and
then remove the gem dependencies from engine's +Gemfile+ and gemspec.
== Contributing
1. Fork it ( https://github.com/nepalez/uuids/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
== TODO
Redefine AR::Base class methods +has_one+ and +has_many+ to allow reference
by uuid:
class MyModel < ActiveRecord::Base
extend Uuids
has_one :another_model, uuid: true
end
== License
The plugin is distributed under {MIT license}[https://github.com/nepalez/uuids/blob/master/LICENSE.rdoc]