uuids 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bfc2367f33f47dad9657d2967ce4b748e250d74d
4
- data.tar.gz: 65bdc11b1153c8a642d8db7cf955551d40f30598
3
+ metadata.gz: 99ef18c3631191192674065383bde357d99af73f
4
+ data.tar.gz: 30e4d290b12cc1a08492356202ad9c3391ab839a
5
5
  SHA512:
6
- metadata.gz: 3727f692aa29305a27f71e6f4a014cecd51f44994093d8045582e69a15124e6a366122a66d135e1536d294ae7ec8a94652b259a0a6045e84a70a49bff85e082b
7
- data.tar.gz: b84266c8b36f76e2540c7706dc31656606c1eb61dbfbc9fc1eeb3a5e149e69e9b6d65ef9ee7d1080fbb1f696fb3ac9aebcd950695cbc19a91908818bf2043e8f
6
+ metadata.gz: 09ba36da96395129310604992a3d8121e520041b251a468d8ebebb559332f9d0e2924308489b6e1ce83a36d6e1b626feaa2ddf4d6842569d345a05e933a980c0
7
+ data.tar.gz: d9f9fa8fe03b4d4b17ee72d72b7797013eb719525d3a2f7091338515667adaa22d065950f9702f0306256bc325ad71f4444eec3d6de29c765ac536d46408d7bb
data/README.rdoc CHANGED
@@ -91,7 +91,7 @@ Add the assotiation to your AR model with a `has_uuids` helper:
91
91
 
92
92
  This will add methods:
93
93
 
94
- +#uuids+:: List of <tt>Uuids::Uuid</tt> objects referred to the record.
94
+ +#uuids+:: List of <tt>Uuids::Models::Uuid</tt> objects referred to the record.
95
95
  <tt>#uuid=(value)</tt>:: assigns the UUID (an alias for <tt>#uuids.new value: value</tt>).
96
96
  +#uuid+:: main UUID for the record - a value of the first +uuids+ (ordered by value).
97
97
  <tt>.by_uuid(*values)</tt>:: A scope for selecting unique records by UUID.
@@ -136,7 +136,40 @@ Instead of <tt>ActiveRecord::Associations</tt> +belongs_to+, +has_one+ and
136
136
  end
137
137
 
138
138
  def city=(city)
139
- read_attribute :city_uuid, city.uuid
139
+ write_attribute :city_uuid, city.uuid
140
+ end
141
+ end
142
+
143
+ === Adding uuid
144
+
145
+ The module also contains the service object +Add+:
146
+
147
+ service = Uuids::Services::Add.new(
148
+ value: "43523547-8230-5723-0457-234057254725",
149
+ record: #<ActiveRecord::Base ... >
150
+ )
151
+ service.subscribe listener
152
+ service.run
153
+
154
+ Depending on the result of creation, the listener will receive either the
155
+ <tt>:created, uuid, messages</tt> or <tt>:error, messages</tt> notification.
156
+
157
+ The service doesn't know what the record is. In the success message it
158
+ will be referred as the record "with id: %{id}".
159
+ To provide more concise messaging, the service should be reloaded with a
160
+ new <tt>name</tt> method.
161
+
162
+ module Users
163
+ module Services
164
+ class AddUuid < Uuids::Services::Add
165
+ private
166
+ def name
167
+ # It is expected the record is a user, that responds to full_name.
168
+ # Not the success message will be something near:
169
+ # "The uuid ... has been added to the record Иван Иванов."
170
+ record.full_name
171
+ end
172
+ end
140
173
  end
141
174
  end
142
175
 
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ module Uuids
4
+
5
+ # The module contains ActiveRecord based models.
6
+ module Models
7
+
8
+ # The model describes uuids assigned to corresponding records.
9
+ # @see http://www.ietf.org/rfc/rfc4122.txt RFC4122 standard.
10
+ # @see https://en.wikipedia.org/wiki/Universally_unique_identifier Wikipedia
11
+ # article.
12
+ #
13
+ # @example
14
+ # # Creates the uuid
15
+ # uuid = Uuids::Models::Uuid.create! record: some_record
16
+ #
17
+ # # Finds a record by uuid
18
+ # Uuid.find_by_value(uuid.value).record # => some_record
19
+ #
20
+ # # Reassigns a uuid to another record
21
+ # uuid.update_attributes! record: another_record
22
+ #
23
+ class Uuid < ActiveRecord::Base
24
+ self.table_name = :uuids_uuids
25
+
26
+ # @!attribute [r] value
27
+ # Assigned by default on creation. Cannot be set or edited manually.
28
+ # @return [String] uuid value as defined in RFC4122.
29
+
30
+ UUID = /[a-z\d]{8}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{12}/
31
+ attr_readonly :value
32
+ validates :value, format: { with: UUID }, allow_nil: true
33
+
34
+ # @!attribute record
35
+ # @return [ActiveRecord::Base] an object the uuid is assigned to.
36
+
37
+ belongs_to :record, polymorphic: true
38
+ validate :record_present?
39
+
40
+ # Callbacks
41
+ after_initialize :set_default_value
42
+ before_destroy :forbid_destruction
43
+
44
+ private
45
+
46
+ # Validates record presence with a custom error message.
47
+ def record_present?
48
+ return if record
49
+ errors.add :record, :blank, uuid: value
50
+ end
51
+
52
+ # Sets a new value by default
53
+ def set_default_value
54
+ self.value = SecureRandom.uuid unless value
55
+ end
56
+
57
+ # Forbids destruction of the record.
58
+ def forbid_destruction
59
+ errors.add :base, :destruction_forbidden
60
+ false
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+
3
+ module Uuids
4
+
5
+ # @api hide
6
+ # Contains complex queries to be used in model scopes.
7
+ module Queries
8
+
9
+ # @api hide
10
+ # The query selects records by uuids.
11
+ #
12
+ # @example Selects records by an array of uuids
13
+ # ByUuid.select(
14
+ # MyModel,
15
+ # [
16
+ # "20547204-3875-0234-7d52-437523057235",
17
+ # "04702362-355e-9237-5e32-da2057054720"
18
+ # ]
19
+ # )
20
+ #
21
+ # @example Selects records by a list of uuids
22
+ # ByUuid.select(
23
+ # MyModel,
24
+ # "20547204-3875-0234-7d52-437523057235",
25
+ # "04702362-355e-9237-5e32-da2057054720"
26
+ # )
27
+ #
28
+ # @example Selects all records when no values given
29
+ # result = ByUuid.select MyModel
30
+ # result == MyModel.all # => true
31
+ class ByUuid < Hexx::Scope
32
+
33
+ # @api hide
34
+ # Initializes the query object.
35
+ # @param [ActiveRecord::Base, #uuids] model The model for selecting
36
+ # records of.
37
+ # @param [Array<String>, nil] values The values to select records by.
38
+ def initialize(model, *values)
39
+ super(model)
40
+ @values = values.flatten
41
+ end
42
+
43
+ # @api hide
44
+ # Runs and returns the query.
45
+ def select
46
+ values.any? ? by_uuid : model.all
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :values
52
+
53
+ def by_uuid
54
+ model.joins(:uuids).where(uuids_uuids: { value: values }).uniq
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+
3
+ module Uuids
4
+
5
+ # The module contains services for managing uuids.
6
+ #
7
+ # Any service implements the Observer pattern using the 'wisper' gem.
8
+ # This means a service doesn't return results to its caller, but calls
9
+ # a corresponding methods of its subscribers ("notifies subscribers").
10
+ #
11
+ # @see http://en.wikipedia.org/wiki/Observer_pattern Observer pattern.
12
+ # @see http://github.com/krisleech/wisper the Wisper gem.
13
+ module Services
14
+
15
+ # Adds the uuid to the record.
16
+ #
17
+ # @example
18
+ # service = Uuids::Services::Add.new(
19
+ # record: #<ActiveRecord::Base ...>,
20
+ # value: "42037503-2753-0570-3257-230403275325",
21
+ # )
22
+ # service.subscribe some_listener
23
+ # service.run
24
+ class Add < Hexx::Service
25
+
26
+ # @!scope class
27
+ # @!method new(params)
28
+ # Constructs the service object.
29
+ # @example (see Uuids::Services::Add)
30
+ # @param [Hash] params The list of service options.
31
+ # @option params [ActiveRecord::Base] :record The record for adding uuid.
32
+ # @option params [String] :value The uuid to be added to the record.
33
+ allow_params :record, :value
34
+
35
+ # @!method subscribe(listener, options = {})
36
+ # Subscribes a listener to receive the service's notifications.
37
+ # @example (see Uuids::Services::Add)
38
+ # @param [Object] listener Any object can be subscribed as a listener.
39
+ # It is expected (but not required) the listener to respond to
40
+ # notifications, published by the {#run}.
41
+ # @param [Hash] options The subscription options.
42
+ # @option options [Symbol] :prefix (nil) The prefix to be added
43
+ # to notifications to provide valid listener method names to call.
44
+
45
+ # Runs the service and publishes its results.
46
+ # @example (see Uuids::Services::Add)
47
+ # @change Creates the uuid assigned to the record.
48
+ # @publish created(uuid,messages) when the uuid has been created.
49
+ # @publish error(messages) when the uuid cannot be created.
50
+ def run
51
+ create_uuid
52
+ end
53
+
54
+ private
55
+
56
+ attr_reader :uuid
57
+
58
+ def create_uuid
59
+ escape do
60
+ @uuid = Models::Uuid.create! record: record, value: value
61
+ on_uuid_created
62
+ end
63
+ end
64
+
65
+ def on_uuid_created
66
+ add_message "success", :created, uuid: uuid, record: name
67
+ publish :created, uuid, messages
68
+ end
69
+
70
+ def name
71
+ t :record, id: record.id
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ # Configures i18n paths
2
+ Dir[File.expand_path("../../locales/**/*.yml", __FILE__)]
3
+ .each { |file| I18n.load_path << file }
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ ---
2
+ en:
3
+ activemodel:
4
+ messages:
5
+ models:
6
+ uuids/services/add:
7
+ created: "The uuid %{uuid} has been added to the record %{record}."
8
+ record: "with id %{id}"
@@ -0,0 +1,8 @@
1
+ ---
2
+ ru:
3
+ activemodel:
4
+ messages:
5
+ models:
6
+ uuids/services/add:
7
+ created: "Добавлен uuid %{uuid} к записи %{record}."
8
+ record: "с id %{id}"
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Creates a table for the Uuids::Uuid model of uuids.
3
+ # Creates a table for the Uuids::Models::Uuid model of uuids.
4
4
  class CreateUuidsUuids < ActiveRecord::Migration
5
5
  def change
6
6
  create_table :uuids_uuids do |t|
@@ -8,27 +8,29 @@ module Uuids
8
8
  # Model scopes.
9
9
  module ClassMethods
10
10
 
11
- # Selects records by uuid.
11
+ # Selects records by uuid(s).
12
12
  #
13
- # @example
14
- # class MyRecord < ActiveRecord::Base
13
+ # @example Selects records by a list of uuids
14
+ # class MyModel < ActiveRecord::Base
15
15
  # include Uuids::Base
16
16
  # has_uuids
17
17
  # end
18
18
  #
19
- # MyRecord.by_uuid(
19
+ # MyModel.by_uuid(
20
20
  # "23423fe3-28d8-a1e5-bde3-2e08074aa92d",
21
21
  # "9223238d-a7e3-2d36-a93d-1e50fea02de2"
22
22
  # )
23
23
  # # => #<ActiveRecord::Relation ...>
24
24
  #
25
- # @param values [Array<String>] a list of uuids to select records by.
25
+ # @example Selects all records without a constraint
26
+ # scope = MyModel.by_uuid
27
+ # scope == MyModel.all # => true
28
+ #
29
+ # @param [Array<String>, nil] values ([]) The list of uuids to select
30
+ # records by.
26
31
  # @return [ActiveRecord::Relation] scope.
27
32
  def by_uuid(*values)
28
- return all unless values.any?
29
- first_value = values.first
30
- list = first_value.is_a?(Array) ? first_value : values
31
- joins(:uuids).where(uuids_uuids: { value: list }).uniq
33
+ Queries::ByUuid.select(self, *values)
32
34
  end
33
35
  end
34
36
 
@@ -72,9 +74,7 @@ module Uuids
72
74
  # @param values [Array<String>] an array of uuids string values to assign
73
75
  # @return object.
74
76
  def uuids=(*values)
75
- first = values.first
76
- list = first.is_a?(Array) ? first : values
77
- list.each { |value| self.uuid = value }
77
+ values.flatten.each { |value| self.uuid = value }
78
78
  end
79
79
 
80
80
  private
data/lib/uuids/base.rb CHANGED
@@ -42,12 +42,23 @@ module Uuids
42
42
  # City.by_uuid("51f50391-fcd2-4f69-aab7-6ef31b29c379").to_a == [city]
43
43
  # # => true
44
44
  def has_uuids
45
- has_many :uuids, class_name: "Uuids::Uuid", as: :record, validate: false
46
45
  include Uuids::Base::HasUuids
46
+ add_association
47
47
  after_initialize :add_default_uuid
48
48
  before_destroy :prevent_destruction
49
49
  validates :uuids, presence: true, on: :update
50
50
  end
51
+
52
+ # @api hide
53
+ # Associates uuids to the current model.
54
+ def add_association
55
+ has_many(
56
+ :uuids,
57
+ class_name: "Uuids::Models::Uuid",
58
+ as: :record,
59
+ validate: false
60
+ )
61
+ end
51
62
  end
52
63
 
53
64
  private
data/lib/uuids/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Uuids
2
2
 
3
3
  # Current release.
4
- VERSION = "3.0.0"
4
+ VERSION = "4.0.0"
5
5
  end
data/lib/uuids.rb CHANGED
@@ -1,12 +1,14 @@
1
1
  # Dependencies
2
- require "active_record"
3
- require "i18n"
2
+ require "hexx-active_record"
4
3
  require "securerandom"
5
4
 
6
5
  # The +uuids+ gem content.
7
6
  root = File.expand_path "../..", __FILE__
8
- Dir[File.join(root, "lib/uuids/**/*.rb")].each { |f| require f }
9
- Dir[File.join(root, "app/**/*.rb")].each { |f| require f }
7
+ Dir[
8
+ "#{ root }/config/initializers/*.rb",
9
+ "#{ root }/lib/uuids/**/*.rb",
10
+ "#{ root }/app/**/*.rb"
11
+ ].each { |file| require file }
10
12
 
11
13
  # Namespace for the +uuids+ gem code.
12
14
  module Uuids
@@ -1,3 +1,3 @@
1
1
  class Record < ActiveRecord::Base
2
- has_many :uuids, class_name: "Uuids::Uuid", as: :record
2
+ has_many :uuids, class_name: "Uuids::Models::Uuid", as: :record
3
3
  end
Binary file
@@ -33,8 +33,8 @@ module Uuids
33
33
  it "defines the #uuids attribute" do
34
34
  subject.uuids.new value: SecureRandom.uuid
35
35
  subject.save!
36
- expect(Uuids::Uuid.first.try(:record)).to eq subject
37
- expect(subject.uuids.first).to eq Uuids::Uuid.first
36
+ expect(Uuids::Models::Uuid.first.try(:record)).to eq subject
37
+ expect(subject.uuids.first).to eq Uuids::Models::Uuid.first
38
38
  end
39
39
 
40
40
  it "defines the #uuid method" do
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- module Uuids
3
+ module Uuids::Models
4
4
  describe Uuid do
5
5
 
6
6
  describe "#value" do
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ module Uuids::Services
5
+ describe Add do
6
+
7
+ let!(:record) { create :record }
8
+ let!(:params) do
9
+ {
10
+ "record" => record,
11
+ "value" => "47027502-4574-3434-0547-032453443434",
12
+ "wrong" => "wrong"
13
+ }
14
+ end
15
+
16
+ describe ".new" do
17
+
18
+ subject { Add.new params }
19
+
20
+ it "sets #record" do
21
+ expect(subject.record).to eq params["record"]
22
+ end
23
+
24
+ it "sets #value" do
25
+ expect(subject.value).to eq params["value"]
26
+ end
27
+
28
+ it "whitelists params" do
29
+ expect(subject.params).to eq params.slice("record", "value")
30
+ end
31
+ end
32
+
33
+ describe "#run" do
34
+
35
+ let(:listener) { double "listener" }
36
+
37
+ context "with valid params" do
38
+
39
+ subject { Add.new params }
40
+
41
+ it "adds a uuid to the record" do
42
+ expect { subject.run }.to change { Uuids::Models::Uuid.count }.by 1
43
+ uuid = Uuids::Models::Uuid.last
44
+ expect(uuid.record).to eq params["record"]
45
+ expect(uuid.value).to eq params["value"]
46
+ end
47
+
48
+ it "publishes :created" do
49
+ subject.subscribe listener
50
+ expect(listener).to receive(:created) do |uuid, messages|
51
+ expect(uuid).to eq Uuids::Models::Uuid.last
52
+ expect(messages).not_to be_blank
53
+ end
54
+ subject.run
55
+ end
56
+ end
57
+
58
+ context "with a wrong value" do
59
+
60
+ subject { Add.new params.merge(value: "wrong") }
61
+
62
+ it "doesn't create a uuid" do
63
+ expect { subject.run }.not_to change { Uuids::Models::Uuid.all }
64
+ end
65
+
66
+ it "publishes :error" do
67
+ subject.subscribe listener
68
+ expect(listener).to receive(:error)
69
+ subject.run
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,7 +1,7 @@
1
1
  require_relative "../config/factory_girl"
2
2
 
3
3
  FactoryGirl.define do
4
- factory :uuid, class: Uuids::Uuid do
4
+ factory :uuid, class: Uuids::Models::Uuid do
5
5
  value { SecureRandom.uuid }
6
6
  record # defined in the `dummy/spec/factories`
7
7
  end
metadata CHANGED
@@ -1,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uuids
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kozin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-26 00:00:00.000000000 Z
11
+ date: 2014-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activerecord
14
+ name: hexx-active_record
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4.1'
19
+ version: '1.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4.1'
27
- - !ruby/object:Gem::Dependency
28
- name: active_record_install
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.4'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '0.4'
26
+ version: '1.3'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: coveralls
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +80,20 @@ dependencies:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
82
  version: '4.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: hexx-generators
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: inch
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -206,16 +206,20 @@ files:
206
206
  - LICENSE.rdoc
207
207
  - README.rdoc
208
208
  - Rakefile
209
- - app/models/uuids/uuid.rb
209
+ - app/models/uuid.rb
210
+ - app/queries/by_uuid.rb
211
+ - app/services/add.rb
210
212
  - bin/uuids
211
- - config/locales/en.yml
212
- - config/locales/ru.yml
213
+ - config/initializers/i18.rb
214
+ - config/locales/models/uuid/en.yml
215
+ - config/locales/models/uuid/ru.yml
216
+ - config/locales/services/add/en.yml
217
+ - config/locales/services/add/ru.yml
213
218
  - db/migrate/20141016112506_create_uuids_uuids.rb
214
219
  - lib/uuids.rb
215
220
  - lib/uuids/base.rb
216
221
  - lib/uuids/base/has_uuids.rb
217
222
  - lib/uuids/version.rb
218
- - spec/app/models/uuids/uuid_spec.rb
219
223
  - spec/bin/uuids_spec.rb
220
224
  - spec/dummy/Rakefile
221
225
  - spec/dummy/app/models/city.rb
@@ -231,6 +235,8 @@ files:
231
235
  - spec/dummy/db/test.sqlite3
232
236
  - spec/dummy/lib/dummy.rb
233
237
  - spec/lib/uuids/base_spec.rb
238
+ - spec/models/uuid_spec.rb
239
+ - spec/services/add_spec.rb
234
240
  - spec/spec_helper.rb
235
241
  - spec/spec_helper_dev.rb
236
242
  - spec/support/all/config/focus.rb
@@ -276,6 +282,7 @@ summary: UUIDs AR model.
276
282
  test_files:
277
283
  - spec/spec_helper_dev.rb
278
284
  - spec/spec_helper.rb
285
+ - spec/models/uuid_spec.rb
279
286
  - spec/dummy/config/environment.rb
280
287
  - spec/dummy/config/database.yml
281
288
  - spec/dummy/config/initializers/seed_loader.rb
@@ -289,8 +296,8 @@ test_files:
289
296
  - spec/dummy/app/models/city.rb
290
297
  - spec/dummy/lib/dummy.rb
291
298
  - spec/dummy/Rakefile
292
- - spec/app/models/uuids/uuid_spec.rb
293
299
  - spec/lib/uuids/base_spec.rb
300
+ - spec/services/add_spec.rb
294
301
  - spec/bin/uuids_spec.rb
295
302
  - spec/support/development/config/timecop.rb
296
303
  - spec/support/development/config/sandbox.rb
@@ -1,58 +0,0 @@
1
- module Uuids
2
-
3
- # The model describes uuids assigned to corresponding records.
4
- # @see http://www.ietf.org/rfc/rfc4122.txt RFC4122 standard.
5
- # @see https://en.wikipedia.org/wiki/Universally_unique_identifier Wikipedia
6
- # article.
7
- #
8
- # @example
9
- # # Creates the uuid
10
- # uuid = Uuids::Uuid.create! record: some_record
11
- #
12
- # # Finds a record by uuid
13
- # Uuid.find_by_value(uuid.value).record # => some_record
14
- #
15
- # # Reassigns a uuid to another record
16
- # uuid.update_attributes! record: another_record
17
- #
18
- class Uuid < ActiveRecord::Base
19
- self.table_name = :uuids_uuids
20
-
21
- # @!attribute [r] value
22
- # Assigned by default on creation. Cannot be set or edited manually.
23
- # @return [String] uuid value as defined in RFC4122.
24
-
25
- UUID = /[a-z\d]{8}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{4}-[a-z\d]{12}/
26
- attr_readonly :value
27
- validates :value, format: { with: UUID }, allow_nil: true
28
-
29
- # @!attribute record
30
- # @return [ActiveRecord::Base] an object the uuid is assigned to.
31
-
32
- belongs_to :record, polymorphic: true
33
- validate :record_present?
34
-
35
- # Callbacks
36
- after_initialize :set_default_value
37
- before_destroy :forbid_destruction
38
-
39
- private
40
-
41
- # Validates record presence with a custom error message.
42
- def record_present?
43
- return if record
44
- errors.add :record, :blank, uuid: value
45
- end
46
-
47
- # Sets a new value by default
48
- def set_default_value
49
- self.value = SecureRandom.uuid unless value
50
- end
51
-
52
- # Forbids destruction of the record.
53
- def forbid_destruction
54
- errors.add :base, :destruction_forbidden
55
- false
56
- end
57
- end
58
- end