activeid 0.6.1
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 +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
|