= UUIDs {Gem Version}[https://rubygems.org/gems/uuids] {Bild Status}[https://travis-ci.org/nepalez/uuids] {Code Metrics}[https://codeclimate.com/github/nepalez/uuids] {Dependency Status}[https://gemnasium.com/nepalez/uuids] {Coverage Status}[https://coveralls.io/r/nepalez/uuids] {License}[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]