activeid 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +21 -0
- data/.github/workflows/macos.yml +45 -0
- data/.github/workflows/ubuntu.yml +47 -0
- data/.github/workflows/windows.yml +40 -0
- data/.gitignore +195 -0
- data/.hound.yml +3 -0
- data/.rubocop.yml +18 -0
- data/Gemfile +7 -0
- data/LICENSE.md +19 -0
- data/README.adoc +411 -0
- data/Rakefile +27 -0
- data/activeid.gemspec +42 -0
- data/examples/name_based_uuids.rb +92 -0
- data/examples/registering_active_record_type.rb +74 -0
- data/examples/storing_uuids_as_binaries.rb +88 -0
- data/examples/storing_uuids_as_strings.rb +81 -0
- data/examples/storing_uuids_natively.rb +93 -0
- data/examples/time_based_uuids.rb +58 -0
- data/examples/using_migrations.rb +50 -0
- data/gemfiles/Rails-5_0.gemfile +8 -0
- data/gemfiles/Rails-5_1.gemfile +8 -0
- data/gemfiles/Rails-5_2.gemfile +8 -0
- data/gemfiles/Rails-head.gemfile +8 -0
- data/lib/active_id.rb +12 -0
- data/lib/active_id/all.rb +2 -0
- data/lib/active_id/connection_patches.rb +65 -0
- data/lib/active_id/model.rb +55 -0
- data/lib/active_id/railtie.rb +12 -0
- data/lib/active_id/type.rb +100 -0
- data/lib/active_id/utils.rb +77 -0
- data/lib/active_id/version.rb +3 -0
- data/spec/integration/examples_for_uuid_models.rb +92 -0
- data/spec/integration/examples_for_uuid_models_having_namespaces.rb +12 -0
- data/spec/integration/examples_for_uuid_models_having_natural_keys.rb +11 -0
- data/spec/integration/migrations_spec.rb +92 -0
- data/spec/integration/model_without_uuids_spec.rb +44 -0
- data/spec/integration/no_patches_spec.rb +26 -0
- data/spec/integration/storing_uuids_as_binaries_spec.rb +34 -0
- data/spec/integration/storing_uuids_as_strings_spec.rb +22 -0
- data/spec/spec_helper.rb +64 -0
- data/spec/support/0_logger.rb +2 -0
- data/spec/support/1_db_connection.rb +3 -0
- data/spec/support/2_db_cleaner.rb +14 -0
- data/spec/support/database.yml +12 -0
- data/spec/support/fabricators.rb +15 -0
- data/spec/support/models.rb +41 -0
- data/spec/support/schema.rb +38 -0
- data/spec/unit/attribute_type_spec.rb +70 -0
- data/spec/unit/utils_spec.rb +97 -0
- metadata +313 -0
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require "rspec/core"
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
|
6
|
+
module TempFixForRakeLastComment
|
7
|
+
def last_comment
|
8
|
+
last_description
|
9
|
+
end
|
10
|
+
end
|
11
|
+
Rake::Application.send :include, TempFixForRakeLastComment
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new(:spec)
|
14
|
+
|
15
|
+
task default: :test
|
16
|
+
|
17
|
+
task test: [:spec, :examples]
|
18
|
+
|
19
|
+
task :examples do
|
20
|
+
Dir.glob("examples/**.rb").sort.each do |example|
|
21
|
+
example_name = File.basename(example, ".rb").tr("_", " ")
|
22
|
+
puts "-" * 40
|
23
|
+
puts "Testing example: #{example_name}"
|
24
|
+
system "ruby", example
|
25
|
+
puts "-" * 40
|
26
|
+
end
|
27
|
+
end
|
data/activeid.gemspec
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$:.push File.expand_path("../lib", __FILE__)
|
4
|
+
require "active_id/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "activeid"
|
8
|
+
s.version = ActiveID::VERSION
|
9
|
+
s.authors = ["Ribose Inc."]
|
10
|
+
s.email = ["open.source@ribose.com"]
|
11
|
+
s.homepage = "https://github.com/riboseinc/activeid"
|
12
|
+
s.summary = "Support for binary UUIDs in ActiveRecord"
|
13
|
+
s.description = "Support for binary UUIDs in ActiveRecord"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_development_dependency "activesupport"
|
21
|
+
s.add_development_dependency "database_cleaner"
|
22
|
+
s.add_development_dependency "fabrication"
|
23
|
+
s.add_development_dependency "forgery"
|
24
|
+
s.add_development_dependency "pry"
|
25
|
+
s.add_development_dependency "rake"
|
26
|
+
s.add_development_dependency "rspec", "~> 3.5"
|
27
|
+
s.add_development_dependency "rspec-its"
|
28
|
+
s.add_development_dependency "solid_assert", "~> 1.0"
|
29
|
+
|
30
|
+
if RUBY_ENGINE == "jruby"
|
31
|
+
s.add_development_dependency "activerecord-jdbcmysql-adapter"
|
32
|
+
s.add_development_dependency "activerecord-jdbcpostgresql-adapter"
|
33
|
+
s.add_development_dependency "activerecord-jdbcsqlite3-adapter"
|
34
|
+
else
|
35
|
+
s.add_development_dependency "mysql2"
|
36
|
+
s.add_development_dependency "pg"
|
37
|
+
s.add_development_dependency "sqlite3", "~> 1.3.6"
|
38
|
+
end
|
39
|
+
|
40
|
+
s.add_runtime_dependency "activerecord", ">= 5.0", "< 6.0"
|
41
|
+
s.add_runtime_dependency "uuidtools"
|
42
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Name-based UUIDs (version 5) are generated deterministically basing
|
2
|
+
# on attribute values and namespace.
|
3
|
+
|
4
|
+
ENV["DB"] ||= "sqlite3"
|
5
|
+
|
6
|
+
require "bundler/setup"
|
7
|
+
Bundler.require :development
|
8
|
+
|
9
|
+
require "active_id"
|
10
|
+
require_relative "../spec/support/0_logger"
|
11
|
+
require_relative "../spec/support/1_db_connection"
|
12
|
+
|
13
|
+
#### SCHEMA ####
|
14
|
+
|
15
|
+
ActiveRecord::Schema.define do
|
16
|
+
create_table :works, id: false, force: true do |t|
|
17
|
+
t.string :id, limit: 36, primary_key: true
|
18
|
+
t.string :author_id, limit: 36, index: true
|
19
|
+
t.string :title
|
20
|
+
t.timestamps
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table :authors, id: false, force: true do |t|
|
24
|
+
t.string :id, limit: 36, primary_key: true
|
25
|
+
t.string :name
|
26
|
+
t.timestamps
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#### MODELS ####
|
31
|
+
|
32
|
+
class Work < ActiveRecord::Base
|
33
|
+
include ActiveID::Model
|
34
|
+
attribute :id, ActiveID::Type::StringUUID.new
|
35
|
+
attribute :author_id, ActiveID::Type::StringUUID.new
|
36
|
+
belongs_to :author
|
37
|
+
natural_key :author_id, :title
|
38
|
+
uuid_namespace "a6908e1e-5493-4c55-a11d-cd8445654de6"
|
39
|
+
end
|
40
|
+
|
41
|
+
class Author < ActiveRecord::Base
|
42
|
+
include ActiveID::Model
|
43
|
+
attribute :id, ActiveID::Type::StringUUID.new
|
44
|
+
has_many :works
|
45
|
+
natural_key :name
|
46
|
+
end
|
47
|
+
|
48
|
+
#### PROOF ####
|
49
|
+
|
50
|
+
SolidAssert.enable_assertions
|
51
|
+
|
52
|
+
poe = Author.create! name: "Edgar Alan Poe"
|
53
|
+
thu = Author.create! name: "Thucydides"
|
54
|
+
|
55
|
+
Work.create! title: "The Raven", author: poe
|
56
|
+
Work.create! title: "The Black Cat", author: poe
|
57
|
+
Work.create! title: "History of the Peloponnesian War", author: thu
|
58
|
+
|
59
|
+
assert Author.count == 2
|
60
|
+
assert Work.count == 3
|
61
|
+
|
62
|
+
assert Author.find_by(name: "Edgar Alan Poe").works.size == 2
|
63
|
+
assert Author.find_by(name: "Thucydides").works.size == 1
|
64
|
+
|
65
|
+
assert UUIDTools::UUID === Author.first.id
|
66
|
+
assert UUIDTools::UUID === Work.first.id
|
67
|
+
assert UUIDTools::UUID === Work.first.author_id
|
68
|
+
|
69
|
+
# Natural keys (UUIDs version 5) are generated deterministically. Hence,
|
70
|
+
# following will succeed despite that id is hardcoded:
|
71
|
+
assert Author.find_by(id: "cb23040c-7635-58f2-a703-434c962821c1") == poe
|
72
|
+
|
73
|
+
# Above UUID has been generated basing on author's name:
|
74
|
+
uuid_namespace = UUIDTools::UUID_OID_NAMESPACE
|
75
|
+
poe_id = UUIDTools::UUID.sha1_create(uuid_namespace, "Edgar Alan Poe")
|
76
|
+
assert Author.find_by(id: poe_id).name == "Edgar Alan Poe"
|
77
|
+
|
78
|
+
# Natural keys can be generated from more than just one field. Also,
|
79
|
+
# a namespace can be set for given model:
|
80
|
+
uuid_namespace = UUIDTools::UUID.parse("a6908e1e-5493-4c55-a11d-cd8445654de6")
|
81
|
+
raven_id = UUIDTools::UUID.sha1_create(uuid_namespace, "#{poe_id}-The Raven")
|
82
|
+
assert Work.find_by(id: raven_id).title == "The Raven"
|
83
|
+
|
84
|
+
#### PROVE THAT ASSERTIONS WERE WORKING ####
|
85
|
+
|
86
|
+
begin
|
87
|
+
assert 1 == 2
|
88
|
+
rescue SolidAssert::AssertionFailedError
|
89
|
+
puts "All OK."
|
90
|
+
else
|
91
|
+
raise "Assertions do not work!"
|
92
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Active UUID types can be added to Active Record's type registry. This is
|
2
|
+
# convenient as you can reference them in your models with a symbol.
|
3
|
+
#
|
4
|
+
# See Rails API docs for more information about +ActiveRecord::Type.register+:
|
5
|
+
# https://api.rubyonrails.org/classes/ActiveRecord/Type.html#method-c-register
|
6
|
+
|
7
|
+
ENV["DB"] ||= "sqlite3"
|
8
|
+
|
9
|
+
require "bundler/setup"
|
10
|
+
Bundler.require :development
|
11
|
+
|
12
|
+
require "active_id"
|
13
|
+
require_relative "../spec/support/0_logger"
|
14
|
+
require_relative "../spec/support/1_db_connection"
|
15
|
+
|
16
|
+
#### SCHEMA ####
|
17
|
+
|
18
|
+
ActiveRecord::Schema.define do
|
19
|
+
create_table :authors, id: false, force: true do |t|
|
20
|
+
if ENV["DB"] == "postgresql"
|
21
|
+
t.uuid :id, primary_key: true
|
22
|
+
else
|
23
|
+
t.binary :id, limit: 16, primary_key: true
|
24
|
+
end
|
25
|
+
t.string :name
|
26
|
+
t.timestamps
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#### TYPE REGISTRATION ####
|
31
|
+
|
32
|
+
ActiveRecord::Type.register(
|
33
|
+
:uuid,
|
34
|
+
ActiveID::Type::BinaryUUID,
|
35
|
+
)
|
36
|
+
|
37
|
+
# In PostgreSQL adapter, +:uuid+ is already registered, but it can be overriden.
|
38
|
+
ActiveRecord::Type.register(
|
39
|
+
:uuid,
|
40
|
+
ActiveID::Type::StringUUID,
|
41
|
+
adapter: :postgresql,
|
42
|
+
override: true,
|
43
|
+
)
|
44
|
+
|
45
|
+
#### MODELS ####
|
46
|
+
|
47
|
+
class Author < ActiveRecord::Base
|
48
|
+
include ActiveID::Model
|
49
|
+
attribute :id, :uuid
|
50
|
+
end
|
51
|
+
|
52
|
+
#### PROOF ####
|
53
|
+
|
54
|
+
SolidAssert.enable_assertions
|
55
|
+
|
56
|
+
Author.create! name: "Edgar Alan Poe"
|
57
|
+
|
58
|
+
assert Author.count == 1
|
59
|
+
|
60
|
+
if ENV["DB"] == "postgresql"
|
61
|
+
assert ActiveID::Type::StringUUID === Author.first.type_for_attribute("id")
|
62
|
+
else
|
63
|
+
assert ActiveID::Type::BinaryUUID === Author.first.type_for_attribute("id")
|
64
|
+
end
|
65
|
+
|
66
|
+
#### PROVE THAT ASSERTIONS WERE WORKING ####
|
67
|
+
|
68
|
+
begin
|
69
|
+
assert 1 == 2
|
70
|
+
rescue SolidAssert::AssertionFailedError
|
71
|
+
puts "All OK."
|
72
|
+
else
|
73
|
+
raise "Assertions do not work!"
|
74
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# See README for comparison between string and binary storage.
|
2
|
+
|
3
|
+
ENV["DB"] ||= "sqlite3"
|
4
|
+
|
5
|
+
if ENV["DB"] == "postgresql"
|
6
|
+
puts <<~MESSAGE
|
7
|
+
Example irrelevant for selected database (#{ENV['DB']}).
|
8
|
+
Storing UUIDs as binaries is not compatible with PostgreSQL adapter.
|
9
|
+
MESSAGE
|
10
|
+
exit(0)
|
11
|
+
end
|
12
|
+
|
13
|
+
require "bundler/setup"
|
14
|
+
Bundler.require :development
|
15
|
+
|
16
|
+
require "active_id"
|
17
|
+
require_relative "../spec/support/0_logger"
|
18
|
+
require_relative "../spec/support/1_db_connection"
|
19
|
+
|
20
|
+
#### SCHEMA ####
|
21
|
+
|
22
|
+
ActiveRecord::Schema.define do
|
23
|
+
create_table :works, id: false, force: true do |t|
|
24
|
+
t.binary :id, limit: 16, primary_key: true
|
25
|
+
t.binary :author_id, limit: 16, index: true
|
26
|
+
t.string :title
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
|
30
|
+
create_table :authors, id: false, force: true do |t|
|
31
|
+
t.binary :id, limit: 16, primary_key: true
|
32
|
+
t.string :name
|
33
|
+
t.timestamps
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
#### MODELS ####
|
38
|
+
|
39
|
+
class Work < ActiveRecord::Base
|
40
|
+
include ActiveID::Model
|
41
|
+
attribute :id, ActiveID::Type::BinaryUUID.new
|
42
|
+
attribute :author_id, ActiveID::Type::BinaryUUID.new
|
43
|
+
belongs_to :author
|
44
|
+
end
|
45
|
+
|
46
|
+
class Author < ActiveRecord::Base
|
47
|
+
include ActiveID::Model
|
48
|
+
attribute :id, ActiveID::Type::BinaryUUID.new
|
49
|
+
has_many :works
|
50
|
+
end
|
51
|
+
|
52
|
+
#### PROOF ####
|
53
|
+
|
54
|
+
SolidAssert.enable_assertions
|
55
|
+
|
56
|
+
poe = Author.create! name: "Edgar Alan Poe"
|
57
|
+
thu = Author.create! name: "Thucydides"
|
58
|
+
|
59
|
+
Work.create! title: "The Raven", author: poe
|
60
|
+
Work.create! title: "The Black Cat", author: poe
|
61
|
+
Work.create! title: "History of the Peloponnesian War", author: thu
|
62
|
+
|
63
|
+
assert Author.count == 2
|
64
|
+
assert Work.count == 3
|
65
|
+
|
66
|
+
assert Author.find_by(name: "Edgar Alan Poe").works.size == 2
|
67
|
+
assert Author.find_by(name: "Thucydides").works.size == 1
|
68
|
+
|
69
|
+
assert UUIDTools::UUID === Author.first.id
|
70
|
+
assert UUIDTools::UUID === Work.first.id
|
71
|
+
assert UUIDTools::UUID === Work.first.author_id
|
72
|
+
|
73
|
+
# Version 4 means randomly generated UUID
|
74
|
+
assert Author.first.id.version == 4
|
75
|
+
|
76
|
+
# UUIDs are stored in database as 16 bytes long binaries
|
77
|
+
raw_id = Author.first.attributes_before_type_cast["id"]
|
78
|
+
assert raw_id.bytes.size == 16
|
79
|
+
|
80
|
+
#### PROVE THAT ASSERTIONS WERE WORKING ####
|
81
|
+
|
82
|
+
begin
|
83
|
+
assert 1 == 2
|
84
|
+
rescue SolidAssert::AssertionFailedError
|
85
|
+
puts "All OK."
|
86
|
+
else
|
87
|
+
raise "Assertions do not work!"
|
88
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# See README for comparison between string and binary storage.
|
2
|
+
|
3
|
+
ENV["DB"] ||= "sqlite3"
|
4
|
+
|
5
|
+
require "bundler/setup"
|
6
|
+
Bundler.require :development
|
7
|
+
|
8
|
+
require "active_id"
|
9
|
+
require_relative "../spec/support/0_logger"
|
10
|
+
require_relative "../spec/support/1_db_connection"
|
11
|
+
|
12
|
+
#### SCHEMA ####
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define do
|
15
|
+
create_table :works, id: false, force: true do |t|
|
16
|
+
t.string :id, limit: 36, primary_key: true
|
17
|
+
t.string :author_id, limit: 36, index: true
|
18
|
+
t.string :title
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table :authors, id: false, force: true do |t|
|
23
|
+
t.string :id, limit: 36, primary_key: true
|
24
|
+
t.string :name
|
25
|
+
t.timestamps
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#### MODELS ####
|
30
|
+
|
31
|
+
class Work < ActiveRecord::Base
|
32
|
+
include ActiveID::Model
|
33
|
+
attribute :id, ActiveID::Type::StringUUID.new
|
34
|
+
attribute :author_id, ActiveID::Type::StringUUID.new
|
35
|
+
belongs_to :author
|
36
|
+
end
|
37
|
+
|
38
|
+
class Author < ActiveRecord::Base
|
39
|
+
include ActiveID::Model
|
40
|
+
attribute :id, ActiveID::Type::StringUUID.new
|
41
|
+
has_many :works
|
42
|
+
end
|
43
|
+
|
44
|
+
#### PROOF ####
|
45
|
+
|
46
|
+
SolidAssert.enable_assertions
|
47
|
+
|
48
|
+
poe = Author.create! name: "Edgar Alan Poe"
|
49
|
+
thu = Author.create! name: "Thucydides"
|
50
|
+
|
51
|
+
Work.create! title: "The Raven", author: poe
|
52
|
+
Work.create! title: "The Black Cat", author: poe
|
53
|
+
Work.create! title: "History of the Peloponnesian War", author: thu
|
54
|
+
|
55
|
+
assert Author.count == 2
|
56
|
+
assert Work.count == 3
|
57
|
+
|
58
|
+
assert Author.find_by(name: "Edgar Alan Poe").works.size == 2
|
59
|
+
assert Author.find_by(name: "Thucydides").works.size == 1
|
60
|
+
|
61
|
+
assert UUIDTools::UUID === Author.first.id
|
62
|
+
assert UUIDTools::UUID === Work.first.id
|
63
|
+
assert UUIDTools::UUID === Work.first.author_id
|
64
|
+
|
65
|
+
# Version 4 means randomly generated UUID
|
66
|
+
assert Author.first.id.version == 4
|
67
|
+
|
68
|
+
# UUIDs are stored in database as 36 characters long strings
|
69
|
+
raw_id = Author.first.attributes_before_type_cast["id"]
|
70
|
+
assert raw_id.chars.size == 36
|
71
|
+
assert /^[-a-f0-9]*$/ =~ raw_id
|
72
|
+
|
73
|
+
#### PROVE THAT ASSERTIONS WERE WORKING ####
|
74
|
+
|
75
|
+
begin
|
76
|
+
assert 1 == 2
|
77
|
+
rescue SolidAssert::AssertionFailedError
|
78
|
+
puts "All OK."
|
79
|
+
else
|
80
|
+
raise "Assertions do not work!"
|
81
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# PostgreSQL natively features a UUID data type, which offerst great performance
|
2
|
+
# without sacrificing human-readability.
|
3
|
+
|
4
|
+
ENV["DB"] ||= "sqlite3"
|
5
|
+
|
6
|
+
unless ENV["DB"] == "postgresql"
|
7
|
+
puts <<~MESSAGE
|
8
|
+
Example irrelevant for selected database (#{ENV['DB']}).
|
9
|
+
From supported databases, only PostgreSQL features
|
10
|
+
a UUID data type natively.
|
11
|
+
MESSAGE
|
12
|
+
exit(0)
|
13
|
+
end
|
14
|
+
|
15
|
+
require "bundler/setup"
|
16
|
+
Bundler.require :development
|
17
|
+
|
18
|
+
require "active_id"
|
19
|
+
require_relative "../spec/support/0_logger"
|
20
|
+
require_relative "../spec/support/1_db_connection"
|
21
|
+
|
22
|
+
#### SCHEMA ####
|
23
|
+
|
24
|
+
# PostgreSQL adapter adds #uuid column method to table definitions
|
25
|
+
|
26
|
+
ActiveRecord::Schema.define do
|
27
|
+
create_table :works, id: false, force: true do |t|
|
28
|
+
t.uuid :id, primary_key: true
|
29
|
+
t.uuid :author_id, index: true
|
30
|
+
t.string :title
|
31
|
+
t.timestamps
|
32
|
+
end
|
33
|
+
|
34
|
+
create_table :authors, id: false, force: true do |t|
|
35
|
+
t.uuid :id, primary_key: true
|
36
|
+
t.string :name
|
37
|
+
t.timestamps
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#### MODELS ####
|
42
|
+
|
43
|
+
class Work < ActiveRecord::Base
|
44
|
+
include ActiveID::Model
|
45
|
+
attribute :id, ActiveID::Type::StringUUID.new
|
46
|
+
attribute :author_id, ActiveID::Type::StringUUID.new
|
47
|
+
belongs_to :author
|
48
|
+
end
|
49
|
+
|
50
|
+
class Author < ActiveRecord::Base
|
51
|
+
include ActiveID::Model
|
52
|
+
attribute :id, ActiveID::Type::StringUUID.new
|
53
|
+
has_many :works
|
54
|
+
end
|
55
|
+
|
56
|
+
#### PROOF ####
|
57
|
+
|
58
|
+
SolidAssert.enable_assertions
|
59
|
+
|
60
|
+
poe = Author.create! name: "Edgar Alan Poe"
|
61
|
+
thu = Author.create! name: "Thucydides"
|
62
|
+
|
63
|
+
Work.create! title: "The Raven", author: poe
|
64
|
+
Work.create! title: "The Black Cat", author: poe
|
65
|
+
Work.create! title: "History of the Peloponnesian War", author: thu
|
66
|
+
|
67
|
+
assert Author.count == 2
|
68
|
+
assert Work.count == 3
|
69
|
+
|
70
|
+
assert Author.find_by(name: "Edgar Alan Poe").works.size == 2
|
71
|
+
assert Author.find_by(name: "Thucydides").works.size == 1
|
72
|
+
|
73
|
+
assert UUIDTools::UUID === Author.first.id
|
74
|
+
assert UUIDTools::UUID === Work.first.id
|
75
|
+
assert UUIDTools::UUID === Work.first.author_id
|
76
|
+
|
77
|
+
# Version 4 means randomly generated UUID
|
78
|
+
assert Author.first.id.version == 4
|
79
|
+
|
80
|
+
# UUIDs are stored in database as 36 characters long strings
|
81
|
+
raw_id = Author.first.attributes_before_type_cast["id"]
|
82
|
+
assert raw_id.chars.size == 36
|
83
|
+
assert /^[-a-f0-9]*$/ =~ raw_id
|
84
|
+
|
85
|
+
#### PROVE THAT ASSERTIONS WERE WORKING ####
|
86
|
+
|
87
|
+
begin
|
88
|
+
assert 1 == 2
|
89
|
+
rescue SolidAssert::AssertionFailedError
|
90
|
+
puts "All OK."
|
91
|
+
else
|
92
|
+
raise "Assertions do not work!"
|
93
|
+
end
|