= 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
The gem adds addressing ActiveRecord objects by {UUID}[http://en.wikipedia.org/wiki/Universally_Unique_Identifier]s following the {RFC4122}[http://www.ietf.org/rfc/rfc4122.txt]
standard.
It provides:
Uuids::Uuid:: A model of UUIDs associated with various records.
Uuids::Base:: A module provides ActiveRecord class helpers +has_uuids+ and +has_many+ (with uuid: true option).
The gem is a {mountable Rails engine}[http://guides.rubyonrails.org/engines.html#generating-an-engine].
=== Pattern
This model allows adressing records by some UUID (not the ID).
It is expected any UUID is assigned to one record, but a record can be
identified by many UUIDs.
If necessary any referred record can be merged with another one.
All you need is to reassign all UUIDs to merged record and outer associations
remains valid.
A **UUID** should be neither deleted, no changed. It can only be reassigned to
another resource. On ther other hand, the outer record should be merged to
another one (reassign UUIDs) to prevent existance of UUIDs assigned to nothing.
=== Example
Suppose you have models referred to cities. One day you discover
a duplication among two 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.
Now the model of cities should **know nothing about outer models** that use it.
=== 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
== Initialization
To initialize the module you need to copy and run uuid's db migrations.
=== Rails application
Run from a command line in application root:
$ rake uuids:install
=== Rails mountable engine
Run from a command line in application root:
$ rake app:uuids:install
== Usage
=== Adding UUIDs to models
Add the assotiation to your AR model:
class City < ActiveRecord::Base
include Uuids::Base
has_uuids
end
This will add methods:
+#uuids+:: List of Uuids::Uuid objects referred to the record.
+#uuid+:: main UUID for the record - a value of the first +uuids+ object.
.by_uuid:: A scope for unique records by UUID: City.by_uuid
The first uuid is added by default. It can also be set manually:
# UUID is generated by default
city = City.new
city.save!
# UUID is assigned manually
city = City.new
city.uuids.new value: "6d9456a9-8f54-4ff7-ba0d-9854f1954417"
city.save
The destruction of object is forbidden if it has a +uuid+. You should reassign
all object's UUIDs to another object in advance.
=== Referring model by UUID
Instead of ActiveRecord::Associations +belongs_to+, +has_one+ and
+has_many+, you should define custom methods explicitly.
class CreateStreetsTable < ActiveRecord::Migration
def change
create_table :streets do |t|
t.string :city_uuid, limit: 36
end
add_index :streets_table, :city_uuid
end
end
class Street < ActiveRecord::Base
scope :by_city, ->(city) { City.by_uuid(city.uuid) }
def city
@city ||= City.by_uuid(city_uuid)
end
def city=(city)
read_attribute :city_uuid, city.uuid
end
end
== 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
== License
The plugin is distributed under {MIT license}[https://github.com/nepalez/uuids/blob/master/LICENSE.rdoc]