uuids 4.0.1 → 4.1.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 +4 -4
- data/.rubocop.yml +4 -2
- data/README.rdoc +15 -23
- data/app/queries/by_uuid.rb +2 -1
- data/lib/uuids/base/belongs_to.rb +123 -0
- data/lib/uuids/base/has_uuids.rb +19 -0
- data/lib/uuids/base.rb +29 -10
- data/lib/uuids/version.rb +1 -1
- data/spec/dummy/app/models/state.rb +6 -0
- data/spec/dummy/db/migrate/20141215182349_create_states.rb +8 -0
- data/spec/dummy/db/migrate/{20141017081115_create_cities.rb → 20151215182355_create_cities.rb} +1 -1
- data/spec/dummy/db/schema.rb +7 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/lib/uuids/base_spec.rb +65 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 016e522c63a1b3f96e575a5e3cc46ebf45d4b7f8
|
4
|
+
data.tar.gz: a23f8b1dc1bbc0e4588294ca6537526bec02d8cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1265400e53725494f22c2a31b4c90de117a8caa5bc16e415aedf3732ddaac2d4ef403268f65a7ff1544f9c65421b5d9b6586abc51ffc3f95c56edceeb58457f5
|
7
|
+
data.tar.gz: e635c00cf24e8c160723d7c9c2716014ec4199f0abfb90966f45685fdcdabcf010a42e7cab3bce6edb662b20821cbf33ab47d0f8ec61c0531b2618584ff82399
|
data/.rubocop.yml
CHANGED
@@ -29,6 +29,9 @@ Style/Documentation:
|
|
29
29
|
- 'db/**/*'
|
30
30
|
- 'lib/uuids/version.rb'
|
31
31
|
|
32
|
+
Style/EmptyLinesAroundBlockBody:
|
33
|
+
Enabled: false
|
34
|
+
|
32
35
|
Style/EmptyLinesAroundClassBody:
|
33
36
|
Enabled: false
|
34
37
|
|
@@ -39,8 +42,7 @@ Style/EmptyLinesAroundModuleBody:
|
|
39
42
|
Enabled: false
|
40
43
|
|
41
44
|
Style/EmptyLineBetweenDefs:
|
42
|
-
|
43
|
-
- 'spec/**/*'
|
45
|
+
Enabled: false
|
44
46
|
|
45
47
|
Style/PredicateName:
|
46
48
|
Enabled: false
|
data/README.rdoc
CHANGED
@@ -60,24 +60,18 @@ Or install it yourself as:
|
|
60
60
|
|
61
61
|
$ gem install uuids
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
After installation you should copy and run uuid's db migration into your module.
|
66
|
-
|
67
|
-
When you install the module to a final application, the migration should be
|
68
|
-
installed to `db/migrate` path directly.
|
63
|
+
Then run the command in the root of a <b>end-up application</b>:
|
69
64
|
|
70
65
|
$ uuids install
|
71
66
|
|
72
|
-
|
73
|
-
|
74
|
-
your gem in a proper environment.
|
75
|
-
|
76
|
-
In this case the migration should be installed to a dummy app in a
|
77
|
-
`spec/dummy/db/migrate` folder. Do it with the `-d` key:
|
67
|
+
Use the <tt>-d</tt> key when installing the gem into a <b>module</b> that is not
|
68
|
+
an end-up application (Rails engine etc.):
|
78
69
|
|
79
70
|
$ uuids install -d
|
80
71
|
|
72
|
+
(this will copy the gem's migrations to the host's dummy folder:
|
73
|
+
+spec/dummy/db/migrate+).
|
74
|
+
|
81
75
|
== Usage
|
82
76
|
|
83
77
|
=== Adding UUIDs to models
|
@@ -86,6 +80,7 @@ Add the assotiation to your AR model with a `has_uuids` helper:
|
|
86
80
|
|
87
81
|
class City < ActiveRecord::Base
|
88
82
|
include Uuids::Base
|
83
|
+
|
89
84
|
has_uuids
|
90
85
|
end
|
91
86
|
|
@@ -113,9 +108,6 @@ all object's UUIDs to another record in advance.
|
|
113
108
|
|
114
109
|
=== Referring model by UUID
|
115
110
|
|
116
|
-
Instead of <tt>ActiveRecord::Associations</tt> +belongs_to+, +has_one+ and
|
117
|
-
+has_many+, you should define custom methods explicitly.
|
118
|
-
|
119
111
|
# db/migrate/*_create_streets.rb
|
120
112
|
class CreateStreetsTable < ActiveRecord::Migration
|
121
113
|
def change
|
@@ -128,17 +120,17 @@ Instead of <tt>ActiveRecord::Associations</tt> +belongs_to+, +has_one+ and
|
|
128
120
|
|
129
121
|
# app/models/street.rb
|
130
122
|
class Street < ActiveRecord::Base
|
123
|
+
include Uuids::Base
|
131
124
|
|
132
|
-
|
125
|
+
belongs_by_uuid_to :city, class: City
|
126
|
+
end
|
133
127
|
|
134
|
-
|
135
|
-
@city ||= City.by_uuid(city_uuid)
|
136
|
-
end
|
128
|
+
This will add both getter and setter for the attribute:
|
137
129
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
130
|
+
street = Street.new name: "Damrak", city: City.new name: "Amsterdam"
|
131
|
+
street.city
|
132
|
+
# => #<City @name="Amsterdam" ... >
|
133
|
+
street.city_uuid == street.city.uuid # => true
|
142
134
|
|
143
135
|
=== Adding uuid
|
144
136
|
|
data/app/queries/by_uuid.rb
CHANGED
@@ -0,0 +1,123 @@
|
|
1
|
+
module Uuids
|
2
|
+
module Base
|
3
|
+
|
4
|
+
# @api hide
|
5
|
+
# Adds getter and setter for the model attribute referred by uuid.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# BelongsTo.add City, :state, State
|
9
|
+
# city = City.new
|
10
|
+
# city.respond_to? :state # => true
|
11
|
+
# city.respond_to? :state= # => true
|
12
|
+
class BelongsTo < Struct.new(:klass, :name, :model)
|
13
|
+
|
14
|
+
# @api hide
|
15
|
+
# @!attribute klass
|
16
|
+
# The model to add the attribute to.
|
17
|
+
# @return [ActiveRecord::Base] The model class.
|
18
|
+
|
19
|
+
# @api hide
|
20
|
+
# @!attribute name
|
21
|
+
# The name of the attribute to be added.
|
22
|
+
# @return [String, Symbol] The name.
|
23
|
+
|
24
|
+
# @api hide
|
25
|
+
# @!attribute model
|
26
|
+
# The model to be referred by uuid.
|
27
|
+
# @return [ActiveRecord::Base] The model class to be referred to.
|
28
|
+
|
29
|
+
# @api hide
|
30
|
+
# @!attribute [r] class_name
|
31
|
+
# The name of the {#klass} constant.
|
32
|
+
# @return [String] The {#klass} name.
|
33
|
+
def class_name
|
34
|
+
@class_name ||= klass.name
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api hide
|
38
|
+
# @!attribute [r] model_name
|
39
|
+
# The name of the {#model} constant.
|
40
|
+
# @return [String] The {#model} name.
|
41
|
+
def model_name
|
42
|
+
@model_name ||= model.name
|
43
|
+
end
|
44
|
+
|
45
|
+
# @api hide
|
46
|
+
# @!attribute [r] model_name
|
47
|
+
# The name of the {#klass} db table column to store reference to the
|
48
|
+
# attribute by uuid.
|
49
|
+
# @return [String] The name of the column.
|
50
|
+
def column_name
|
51
|
+
@column_name ||= "#{ name }_uuid"
|
52
|
+
end
|
53
|
+
|
54
|
+
# @api hide
|
55
|
+
# Constructs the object and adds the attribute.
|
56
|
+
# @example (see Uuids::Base::BelongsTo)
|
57
|
+
# @params [ActiveRecord::Base] klass The model to add attribute to.
|
58
|
+
# Should have a corresponding column for reference by uuid.
|
59
|
+
# @params [String, Symbol] name The name of the attribute to be added.
|
60
|
+
# @params [ActiveRecord::Base] model The model to be referred by uuid.
|
61
|
+
# Should include the <tt>Uuids::Base</tt> module.
|
62
|
+
# @raise (see Uuids::Base::BelongsTo#add)
|
63
|
+
def self.add(*args)
|
64
|
+
new(*args).add
|
65
|
+
end
|
66
|
+
|
67
|
+
# @api hide
|
68
|
+
# Adds the attribute's getter and setter.
|
69
|
+
# @raise [TypeError] if the {#model} doesn't include
|
70
|
+
# the <tt>Uuids::Base</tt> module.
|
71
|
+
# @raise [NotImplementedError] if the {#klass} doesn't have the
|
72
|
+
# correspondint {#column_name} column.
|
73
|
+
def add
|
74
|
+
check_model
|
75
|
+
check_column
|
76
|
+
add_getter
|
77
|
+
add_setter
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def check_model
|
83
|
+
return if model.ancestors.include? Uuids::Base
|
84
|
+
fail TypeError
|
85
|
+
.new "#{ model_name } class doesn't include the Uuids::Base module"
|
86
|
+
end
|
87
|
+
|
88
|
+
def check_column
|
89
|
+
return if klass.attribute_names.include? column_name
|
90
|
+
fail NotImplementedError
|
91
|
+
.new "#{ class_name }##{ column_name } attribute isn't implemented"
|
92
|
+
end
|
93
|
+
|
94
|
+
def add_getter
|
95
|
+
klass.class_eval getter
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_setter
|
99
|
+
klass.class_eval setter
|
100
|
+
end
|
101
|
+
|
102
|
+
def getter
|
103
|
+
"def #{ name };
|
104
|
+
uuid = read_attribute :#{ column_name };
|
105
|
+
return @#{ name } = nil unless uuid;
|
106
|
+
if Array(@#{ name }.try(:uuids)).map(&:value).include? uuid;
|
107
|
+
@#{ name };
|
108
|
+
else;
|
109
|
+
@#{ name } = #{ model_name }.by_uuid(uuid).includes(:uuids).first;
|
110
|
+
end;
|
111
|
+
end"
|
112
|
+
end
|
113
|
+
|
114
|
+
def setter
|
115
|
+
"def #{ name }=(value);
|
116
|
+
fail TypeError unless value.nil? || value.is_a?(#{ model_name });
|
117
|
+
write_attribute :#{ column_name }, value.try(:uuid);
|
118
|
+
#{ name };
|
119
|
+
end"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/uuids/base/has_uuids.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
module Uuids
|
2
2
|
module Base
|
3
3
|
|
4
|
+
# @api hide
|
4
5
|
# Defines methods to be added by the +has_uuids+ class helper.
|
5
6
|
module HasUuids
|
6
7
|
extend ActiveSupport::Concern
|
7
8
|
|
9
|
+
# @api hide
|
8
10
|
# Model scopes.
|
9
11
|
module ClassMethods
|
10
12
|
|
13
|
+
# @api hide
|
11
14
|
# Selects records by uuid(s).
|
12
15
|
#
|
13
16
|
# @example Selects records by a list of uuids
|
@@ -32,8 +35,22 @@ module Uuids
|
|
32
35
|
def by_uuid(*values)
|
33
36
|
Queries::ByUuid.select(self, *values)
|
34
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @api hide
|
42
|
+
# Associates uuids to the current model.
|
43
|
+
def has_many_uuids
|
44
|
+
has_many(
|
45
|
+
:uuids,
|
46
|
+
class_name: "Uuids::Models::Uuid",
|
47
|
+
as: :record,
|
48
|
+
validate: false
|
49
|
+
)
|
50
|
+
end
|
35
51
|
end
|
36
52
|
|
53
|
+
# @api hide
|
37
54
|
# Returns the first UUID (sorted as a string) for the record.
|
38
55
|
#
|
39
56
|
# @example
|
@@ -46,6 +63,7 @@ module Uuids
|
|
46
63
|
uuids.map(&:value).sort.first
|
47
64
|
end
|
48
65
|
|
66
|
+
# @api hide
|
49
67
|
# Assigns a new uuid to the record.
|
50
68
|
#
|
51
69
|
# @example
|
@@ -58,6 +76,7 @@ module Uuids
|
|
58
76
|
uuids.new value: value
|
59
77
|
end
|
60
78
|
|
79
|
+
# @api hide
|
61
80
|
# Assigns a list of new uuids to the record.
|
62
81
|
#
|
63
82
|
# @example
|
data/lib/uuids/base.rb
CHANGED
@@ -21,6 +21,8 @@ module Uuids
|
|
21
21
|
#
|
22
22
|
# @example
|
23
23
|
# class City < ActiveRecord::Base
|
24
|
+
# include Uuids::Base
|
25
|
+
#
|
24
26
|
# has_uuids
|
25
27
|
# end
|
26
28
|
#
|
@@ -43,21 +45,38 @@ module Uuids
|
|
43
45
|
# # => true
|
44
46
|
def has_uuids
|
45
47
|
include Uuids::Base::HasUuids
|
46
|
-
|
48
|
+
has_many_uuids
|
47
49
|
after_initialize :add_default_uuid
|
48
50
|
before_destroy :prevent_destruction
|
49
51
|
validates :uuids, presence: true, on: :update
|
50
52
|
end
|
51
53
|
|
52
|
-
#
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
# The helper defines both the getter and setter for object, associated
|
55
|
+
# by uuid.
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# class City < ActiveRecord::Base
|
59
|
+
# include Uuids::Base
|
60
|
+
#
|
61
|
+
# belongs_by_uuid_to :state, class: State
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# city = City.new
|
65
|
+
# city.state_uuid = "12345678-90ab-cdef-1234-567890abcdef"
|
66
|
+
#
|
67
|
+
# city.state.class # => State
|
68
|
+
# city.state.uuid # => "12345678-90ab-cdef-1234-567890abcdef"
|
69
|
+
#
|
70
|
+
# city.state = State.new uuid: "fedcba98-7654-3210-fedc-ba9876543210"
|
71
|
+
# city.state.uuid # => "fedcba98-7654-3210-fedc-ba9876543210"
|
72
|
+
#
|
73
|
+
# @param [String, Symbol] name The name of the attribute.
|
74
|
+
# @param [Hash] options The options for the association.
|
75
|
+
# @option options [Class] :class The model of the attribute.
|
76
|
+
# @option options [String] :class_name The name of the attribute's model.
|
77
|
+
def belongs_by_uuid_to(name, options = {})
|
78
|
+
class_name = options[:class] || options[:class_name].constantize
|
79
|
+
BelongsTo.add self, name, class_name
|
61
80
|
end
|
62
81
|
end
|
63
82
|
|
data/lib/uuids/version.rb
CHANGED
data/spec/dummy/db/schema.rb
CHANGED
@@ -11,9 +11,10 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
14
|
+
ActiveRecord::Schema.define(version: 20151215182355) do
|
15
15
|
|
16
16
|
create_table "cities", force: true do |t|
|
17
|
+
t.string "state_uuid", limit: 36
|
17
18
|
t.datetime "created_at"
|
18
19
|
t.datetime "updated_at"
|
19
20
|
end
|
@@ -23,6 +24,11 @@ ActiveRecord::Schema.define(version: 20141017081115) do
|
|
23
24
|
t.datetime "updated_at"
|
24
25
|
end
|
25
26
|
|
27
|
+
create_table "states", force: true do |t|
|
28
|
+
t.datetime "created_at"
|
29
|
+
t.datetime "updated_at"
|
30
|
+
end
|
31
|
+
|
26
32
|
create_table "uuids_uuids", force: true do |t|
|
27
33
|
t.string "value", limit: 36, null: false
|
28
34
|
t.integer "record_id", null: false
|
data/spec/dummy/db/test.sqlite3
CHANGED
Binary file
|
data/spec/lib/uuids/base_spec.rb
CHANGED
@@ -81,5 +81,70 @@ module Uuids
|
|
81
81
|
expect { subject.destroy! }.not_to raise_error
|
82
82
|
end
|
83
83
|
end
|
84
|
+
|
85
|
+
describe ".belongs_by_uuid_to" do
|
86
|
+
|
87
|
+
context "when a model doesn't include Uuids::Base" do
|
88
|
+
|
89
|
+
it "raises TypeError" do
|
90
|
+
expect { City.send :belongs_by_uuid_to, :state, class: Record }
|
91
|
+
.to raise_error { TypeError }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when a class doesn't have column for uuids" do
|
96
|
+
|
97
|
+
it "raises NotImplementedError" do
|
98
|
+
expect { City.send :belongs_by_uuid_to, :country, class: State }
|
99
|
+
.to raise_error { NotImplementedError }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "with valid arguments" do
|
104
|
+
|
105
|
+
before { City.send :belongs_by_uuid_to, :state, class: State }
|
106
|
+
subject { City.new }
|
107
|
+
|
108
|
+
let!(:uuid) { "01234567-89ab-cdef-0123-456789abcdef" }
|
109
|
+
let!(:state) { State.create uuid: uuid }
|
110
|
+
|
111
|
+
it "defines the getter" do
|
112
|
+
expect(subject).to respond_to :state
|
113
|
+
expect(subject.method(:state).arity).to eq 0
|
114
|
+
end
|
115
|
+
|
116
|
+
it "defines the setter" do
|
117
|
+
expect(subject).to respond_to :state=
|
118
|
+
expect(subject.method(:state=).arity).to eq 1
|
119
|
+
end
|
120
|
+
|
121
|
+
it "sets the object" do
|
122
|
+
expect { subject.state = state }
|
123
|
+
.to change { subject.state }.to state
|
124
|
+
end
|
125
|
+
|
126
|
+
it "sets the object uuid" do
|
127
|
+
expect { subject.state = state }
|
128
|
+
.to change { subject.state_uuid }.to state.uuid
|
129
|
+
end
|
130
|
+
|
131
|
+
it "resets the object" do
|
132
|
+
subject.state = state
|
133
|
+
expect { subject.state = nil }
|
134
|
+
.to change { subject.state }.to nil
|
135
|
+
end
|
136
|
+
|
137
|
+
it "resets the object uuid" do
|
138
|
+
subject.state = state
|
139
|
+
expect { subject.state = nil }
|
140
|
+
.to change { subject.state_uuid }.to nil
|
141
|
+
end
|
142
|
+
|
143
|
+
it "sets the object by uuid" do
|
144
|
+
expect { subject.state_uuid = state.uuid }
|
145
|
+
.to change { subject.state }.to state
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
84
149
|
end
|
85
150
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uuids
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kozin
|
@@ -218,19 +218,22 @@ files:
|
|
218
218
|
- db/migrate/20141016112506_create_uuids_uuids.rb
|
219
219
|
- lib/uuids.rb
|
220
220
|
- lib/uuids/base.rb
|
221
|
+
- lib/uuids/base/belongs_to.rb
|
221
222
|
- lib/uuids/base/has_uuids.rb
|
222
223
|
- lib/uuids/version.rb
|
223
224
|
- spec/bin/uuids_spec.rb
|
224
225
|
- spec/dummy/Rakefile
|
225
226
|
- spec/dummy/app/models/city.rb
|
226
227
|
- spec/dummy/app/models/record.rb
|
228
|
+
- spec/dummy/app/models/state.rb
|
227
229
|
- spec/dummy/config/database.yml
|
228
230
|
- spec/dummy/config/environment.rb
|
229
231
|
- spec/dummy/config/initializers/application.rb
|
230
232
|
- spec/dummy/config/initializers/dummy.rb
|
231
233
|
- spec/dummy/config/initializers/seed_loader.rb
|
232
234
|
- spec/dummy/db/migrate/20141016113016_create_records.rb
|
233
|
-
- spec/dummy/db/migrate/
|
235
|
+
- spec/dummy/db/migrate/20141215182349_create_states.rb
|
236
|
+
- spec/dummy/db/migrate/20151215182355_create_cities.rb
|
234
237
|
- spec/dummy/db/schema.rb
|
235
238
|
- spec/dummy/db/test.sqlite3
|
236
239
|
- spec/dummy/lib/dummy.rb
|
@@ -288,10 +291,12 @@ test_files:
|
|
288
291
|
- spec/dummy/config/initializers/seed_loader.rb
|
289
292
|
- spec/dummy/config/initializers/application.rb
|
290
293
|
- spec/dummy/config/initializers/dummy.rb
|
291
|
-
- spec/dummy/db/migrate/
|
294
|
+
- spec/dummy/db/migrate/20141215182349_create_states.rb
|
292
295
|
- spec/dummy/db/migrate/20141016113016_create_records.rb
|
296
|
+
- spec/dummy/db/migrate/20151215182355_create_cities.rb
|
293
297
|
- spec/dummy/db/test.sqlite3
|
294
298
|
- spec/dummy/db/schema.rb
|
299
|
+
- spec/dummy/app/models/state.rb
|
295
300
|
- spec/dummy/app/models/record.rb
|
296
301
|
- spec/dummy/app/models/city.rb
|
297
302
|
- spec/dummy/lib/dummy.rb
|