identifiable 0.1.0 → 1.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 +4 -4
- data/.github/workflows/ci.yml +6 -6
- data/.rubocop.yml +11 -0
- data/.tool-versions +1 -1
- data/CHANGELOG.md +39 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +80 -51
- data/README.md +41 -8
- data/Rakefile +2 -2
- data/bin/console +3 -3
- data/bin/rspec +29 -0
- data/bin/rubocop +27 -0
- data/identifiable.gemspec +16 -15
- data/lib/identifiable/configuration.rb +12 -0
- data/lib/identifiable/errors.rb +10 -10
- data/lib/identifiable/model.rb +25 -1
- data/lib/identifiable/version.rb +1 -1
- data/lib/identifiable.rb +19 -8
- metadata +13 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e229c2c8c0e8206c88cdbd14e66472bb7e16a65ab0d0db94e4e312622224fca1
|
4
|
+
data.tar.gz: 6898197f22c73a31ea84585076b2638427dbc184b5a60ae8e3ba7cc5d9309782
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 462f3c632763996b78500c622433e2e058914ee0136b9c6a4478085f09270ae9f604dea0e6c1f31f9a11fda4366f018ba1d755617c9a12431f5ff9757f6fab47
|
7
|
+
data.tar.gz: 715519049734d87cce4399ab2e5c510e88b4bbe4626b53986a4e21ed9d68e6cbfa3e110c6829c71b369765e5e3efd3b648c747f49207818b04cfaa19db5a92ad
|
data/.github/workflows/ci.yml
CHANGED
@@ -5,14 +5,14 @@ jobs:
|
|
5
5
|
name: 'Test Suite'
|
6
6
|
strategy:
|
7
7
|
matrix:
|
8
|
-
ruby: [2.
|
8
|
+
ruby: [3.2.8, 3.3.8, 3.4.4]
|
9
9
|
runs-on: ubuntu-latest
|
10
10
|
steps:
|
11
11
|
- uses: actions/checkout@v2
|
12
12
|
- uses: ruby/setup-ruby@v1
|
13
13
|
with:
|
14
14
|
ruby-version: ${{ matrix.ruby }}
|
15
|
-
- uses: actions/cache@
|
15
|
+
- uses: actions/cache@v4
|
16
16
|
with:
|
17
17
|
path: vendor/bundle
|
18
18
|
key: bundle-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}
|
@@ -26,11 +26,11 @@ jobs:
|
|
26
26
|
- uses: actions/checkout@v2
|
27
27
|
- uses: ruby/setup-ruby@v1
|
28
28
|
with:
|
29
|
-
ruby-version: 2.
|
30
|
-
- uses: actions/cache@
|
29
|
+
ruby-version: 3.2.8
|
30
|
+
- uses: actions/cache@v4
|
31
31
|
with:
|
32
32
|
path: vendor/bundle
|
33
|
-
key: bundle-2.
|
34
|
-
restore-keys: bundle-2.
|
33
|
+
key: bundle-3.2.8-${{ hashFiles('**/*.gemspec') }}
|
34
|
+
restore-keys: bundle-3.2.8
|
35
35
|
- run: bundle install --jobs 4 --retry 3 --path vendor/bundle
|
36
36
|
- run: bundle exec rubocop
|
data/.rubocop.yml
CHANGED
@@ -1,9 +1,20 @@
|
|
1
1
|
AllCops:
|
2
2
|
NewCops: enable
|
3
|
+
SuggestExtensions: false
|
4
|
+
|
5
|
+
Gemspec/RequiredRubyVersion:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Gemspec/DevelopmentDependencies:
|
9
|
+
Enabled: false
|
3
10
|
|
4
11
|
Style/Documentation:
|
5
12
|
Enabled: false
|
6
13
|
|
14
|
+
Style/StringLiterals:
|
15
|
+
Enabled: true
|
16
|
+
EnforcedStyle: double_quotes
|
17
|
+
|
7
18
|
Layout/LineLength:
|
8
19
|
Enabled: false
|
9
20
|
|
data/.tool-versions
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby 2.
|
1
|
+
ruby 3.2.0
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
## Unreleased
|
6
|
+
|
7
|
+
*Nothing yet*
|
8
|
+
|
9
|
+
## 1.0.0 - Released June 22, 2025
|
10
|
+
|
11
|
+
### Added
|
12
|
+
- **Configuration system**: Use `Identifiable.configure` to set the `overwrite_to_key` and `overwrite_to_param` options that control whether Identifiable overrides Rails' `to_key` and `to_param` model methods. Both options default to `true` to maintain backward compatibility.
|
13
|
+
- Support for Ruby version 3.2, 3.3, and 3.4.
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
- This is now considered a stable 1.0 release.
|
17
|
+
|
18
|
+
### Removed
|
19
|
+
- Support for Ruby 2.7, 3.0, and 3.1. The new minimum supported Ruby version is 3.2.
|
20
|
+
- Support for Rails versions below 7.0. The new minimum supported Rails version is 7.0.
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
- Configuration options resolve compatibility issues with other gems like Devise (#7).
|
24
|
+
|
25
|
+
## 0.2.0 - Released October 16, 2022
|
26
|
+
|
27
|
+
### Added
|
28
|
+
- Support for Ruby versions 3.0 and 3.1.
|
29
|
+
- Models that include identifiable will now use Identifiable's public ID for the `#to_key` and `#to_param` methods, meaning that you can now use Rails helpers like `dom_id(@order)` and `order_path(@order)`, and they'll use public IDs instead of the database primary key.
|
30
|
+
|
31
|
+
### Removed
|
32
|
+
- Support for Ruby 2.5 and 2.6. The new minimum supported Ruby version is 2.7.
|
33
|
+
|
34
|
+
### Fixed
|
35
|
+
- A migration will no longer fail if the model has identifiable but the table doesn't exist yet.
|
36
|
+
|
37
|
+
## 0.1.0 - Released November 15, 2020
|
38
|
+
|
39
|
+
This is the early, initial release of Identifiable.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,70 +1,99 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
identifiable (
|
5
|
-
activerecord (>
|
4
|
+
identifiable (1.0.0)
|
5
|
+
activerecord (> 7)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activemodel (
|
11
|
-
activesupport (=
|
12
|
-
activerecord (
|
13
|
-
activemodel (=
|
14
|
-
activesupport (=
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
10
|
+
activemodel (8.0.2)
|
11
|
+
activesupport (= 8.0.2)
|
12
|
+
activerecord (8.0.2)
|
13
|
+
activemodel (= 8.0.2)
|
14
|
+
activesupport (= 8.0.2)
|
15
|
+
timeout (>= 0.4.0)
|
16
|
+
activesupport (8.0.2)
|
17
|
+
base64
|
18
|
+
benchmark (>= 0.3)
|
19
|
+
bigdecimal
|
20
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
21
|
+
connection_pool (>= 2.2.5)
|
22
|
+
drb
|
23
|
+
i18n (>= 1.6, < 2)
|
24
|
+
logger (>= 1.4.2)
|
25
|
+
minitest (>= 5.1)
|
26
|
+
securerandom (>= 0.3)
|
27
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
28
|
+
uri (>= 0.13.1)
|
29
|
+
ast (2.4.3)
|
30
|
+
base64 (0.3.0)
|
31
|
+
benchmark (0.4.1)
|
32
|
+
bigdecimal (3.2.2)
|
33
|
+
concurrent-ruby (1.3.5)
|
34
|
+
connection_pool (2.5.3)
|
35
|
+
diff-lcs (1.6.2)
|
36
|
+
drb (2.2.3)
|
37
|
+
i18n (1.14.7)
|
25
38
|
concurrent-ruby (~> 1.0)
|
26
|
-
|
27
|
-
|
28
|
-
|
39
|
+
json (2.12.2)
|
40
|
+
language_server-protocol (3.17.0.5)
|
41
|
+
lint_roller (1.1.0)
|
42
|
+
logger (1.7.0)
|
43
|
+
mini_portile2 (2.8.9)
|
44
|
+
minitest (5.25.5)
|
45
|
+
parallel (1.27.0)
|
46
|
+
parser (3.3.8.0)
|
29
47
|
ast (~> 2.4.1)
|
30
|
-
|
48
|
+
racc
|
49
|
+
prism (1.4.0)
|
50
|
+
racc (1.8.1)
|
51
|
+
rainbow (3.1.1)
|
31
52
|
rake (12.3.3)
|
32
|
-
regexp_parser (
|
33
|
-
|
34
|
-
|
35
|
-
rspec-
|
36
|
-
rspec-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
rspec-expectations (3.10.0)
|
53
|
+
regexp_parser (2.10.0)
|
54
|
+
rspec (3.13.1)
|
55
|
+
rspec-core (~> 3.13.0)
|
56
|
+
rspec-expectations (~> 3.13.0)
|
57
|
+
rspec-mocks (~> 3.13.0)
|
58
|
+
rspec-core (3.13.4)
|
59
|
+
rspec-support (~> 3.13.0)
|
60
|
+
rspec-expectations (3.13.5)
|
41
61
|
diff-lcs (>= 1.2.0, < 2.0)
|
42
|
-
rspec-support (~> 3.
|
43
|
-
rspec-mocks (3.
|
62
|
+
rspec-support (~> 3.13.0)
|
63
|
+
rspec-mocks (3.13.5)
|
44
64
|
diff-lcs (>= 1.2.0, < 2.0)
|
45
|
-
rspec-support (~> 3.
|
46
|
-
rspec-support (3.
|
47
|
-
rubocop (1.
|
65
|
+
rspec-support (~> 3.13.0)
|
66
|
+
rspec-support (3.13.4)
|
67
|
+
rubocop (1.77.0)
|
68
|
+
json (~> 2.3)
|
69
|
+
language_server-protocol (~> 3.17.0.2)
|
70
|
+
lint_roller (~> 1.1.0)
|
48
71
|
parallel (~> 1.10)
|
49
|
-
parser (>=
|
72
|
+
parser (>= 3.3.0.2)
|
50
73
|
rainbow (>= 2.2.2, < 4.0)
|
51
|
-
regexp_parser (>=
|
52
|
-
|
53
|
-
rubocop-ast (>= 1.1.1)
|
74
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
75
|
+
rubocop-ast (>= 1.45.1, < 2.0)
|
54
76
|
ruby-progressbar (~> 1.7)
|
55
|
-
unicode-display_width (>=
|
56
|
-
rubocop-ast (1.
|
57
|
-
parser (>=
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
77
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
78
|
+
rubocop-ast (1.45.1)
|
79
|
+
parser (>= 3.3.7.2)
|
80
|
+
prism (~> 1.4)
|
81
|
+
ruby-progressbar (1.13.0)
|
82
|
+
securerandom (0.4.1)
|
83
|
+
sqlite3 (2.7.0)
|
84
|
+
mini_portile2 (~> 2.8.0)
|
85
|
+
sqlite3 (2.7.0-arm64-darwin)
|
86
|
+
timeout (0.4.3)
|
87
|
+
tzinfo (2.0.6)
|
88
|
+
concurrent-ruby (~> 1.0)
|
89
|
+
unicode-display_width (3.1.4)
|
90
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
91
|
+
unicode-emoji (4.0.4)
|
92
|
+
uri (1.0.3)
|
65
93
|
|
66
94
|
PLATFORMS
|
67
|
-
|
95
|
+
arm64-darwin-25
|
96
|
+
x84_64-linux
|
68
97
|
|
69
98
|
DEPENDENCIES
|
70
99
|
identifiable!
|
@@ -74,4 +103,4 @@ DEPENDENCIES
|
|
74
103
|
sqlite3
|
75
104
|
|
76
105
|
BUNDLED WITH
|
77
|
-
2.1
|
106
|
+
2.4.1
|
data/README.md
CHANGED
@@ -13,10 +13,10 @@ Identifiable makes it really simple to generate and use random public-facing IDs
|
|
13
13
|
|
14
14
|
```ruby
|
15
15
|
# Before:
|
16
|
-
orders_url(
|
16
|
+
orders_url(@order) # → https://example.app/orders/14
|
17
17
|
|
18
18
|
# After:
|
19
|
-
orders_url(
|
19
|
+
orders_url(@order) # → https://example.app/orders/87133275
|
20
20
|
```
|
21
21
|
|
22
22
|
## Installation
|
@@ -72,7 +72,7 @@ While Identifiable strives to have useful defaults, you may want to customize yo
|
|
72
72
|
|
73
73
|
### Different public ID styles
|
74
74
|
|
75
|
-
By default, Identifiable will generate numeric public IDs, with each character between 0 and 9, but it can also generate alphanumeric public IDs and UUID public
|
75
|
+
By default, Identifiable will generate numeric public IDs, with each character between 0 and 9, but it can also generate alphanumeric public IDs and UUID public IDs. To choose your public ID style, simply pass it in as a parameter to `identifiable` on your model.
|
76
76
|
|
77
77
|
```ruby
|
78
78
|
class Order < ApplicationRecord
|
@@ -112,14 +112,47 @@ end
|
|
112
112
|
|
113
113
|
The `length` parameter is ignored if you're using `style: :uuid`, because UUIDs already have a fixed length. The `length` parameter also needs be an Integer, and can't be less than `4` or greater than `128`. If any of these constraints are broken, Identifiable will raise an error letting you know.
|
114
114
|
|
115
|
+
## Configuration
|
116
|
+
|
117
|
+
By default, Identifiable overrides Rails' `to_key` and `to_param` methods so that your URLs and DOM IDs will use your public IDs instead of your database IDs.
|
118
|
+
|
119
|
+
This can break other gems that rely on the default behavior of Rails' `to_key` and `to_param` methods, like devise! You can configure Identifiable to not override these methods if you'd like:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
# In config/initializers/identifiable.rb
|
123
|
+
Identifiable.configure do |config|
|
124
|
+
config.overwrite_to_key = false
|
125
|
+
config.overwrite_to_param = false
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
The `overwrite_to_key` option controls whether Rails helpers like `dom_id` use your public ID or your database ID. The default value is `true`.
|
130
|
+
|
131
|
+
The `overwrite_to_param` option controls whether URL helpers use your public ID or your database ID in routes. The default value is `true`.
|
132
|
+
|
133
|
+
If you disable both options, your application will behave like this:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
@order = Order.last
|
137
|
+
@order.id # => 14
|
138
|
+
@order.public_id # => "87133275"
|
139
|
+
orders_url(@order) # => https://example.app/orders/14
|
140
|
+
|
141
|
+
# But you can still create URLs using the public ID
|
142
|
+
orders_url(@order.public_id) # => https://example.app/orders/87133275
|
143
|
+
```
|
144
|
+
|
145
|
+
## Alternatives
|
146
|
+
|
147
|
+
I built Identifiable because I never could quite get the other gems that do similar things quite the way that I liked them. You might have the same experience with Identifiable, so if you try Identifiable and find that it's not quite to your tastes, try out some of these alternatives:
|
148
|
+
|
149
|
+
* [**Hashid Rails**](https://github.com/jcypret/hashid-rails) uses [hashids](http://hashids.org/ruby) to seamlessly create hex strings for your primary keys. It's nice because it doesn't require an extra column in your database, but it's limited in what it can do.
|
150
|
+
* [**Public UID**](https://github.com/equivalent/public_uid) is a real power-users public ID gem, and until I made this it was the main way I would build public ID features into the apps I was working on, but I found it too heavy for what I wanted 90% of the time, which is why Identifiable is customizable, but not _too_ customizable. If you find Identifiable isn't customizable or powerful enough for your needs, give Public UID a go!
|
151
|
+
|
115
152
|
## Contributing
|
116
153
|
|
117
|
-
Bug reports and pull requests are welcome on [GitHub](https://github.com/tpritc/identifiable). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/tpritc/identifiable/blob/main/CODE_OF_CONDUCT.md).
|
154
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/tpritc/identifiable). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/tpritc/identifiable/blob/main/CODE_OF_CONDUCT.md) while interacting in the project's codebases, issue trackers, chat rooms, and mailing lists.
|
118
155
|
|
119
156
|
## License
|
120
157
|
|
121
158
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). If you or your organization need a custom, commercial license for any reason, [send me an email](mailto:hi@tpritc.com) and I'll be happy to set something up for you.
|
122
|
-
|
123
|
-
## Code of Conduct
|
124
|
-
|
125
|
-
Everyone interacting in the Identifiable project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/tpritc/identifiable/blob/main/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "bundler/setup"
|
5
|
+
require "identifiable"
|
6
6
|
|
7
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -11,5 +11,5 @@ require 'identifiable'
|
|
11
11
|
# require "pry"
|
12
12
|
# Pry.start
|
13
13
|
|
14
|
-
require
|
14
|
+
require "irb"
|
15
15
|
IRB.start(__FILE__)
|
data/bin/rspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/bin/rubocop
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/identifiable.gemspec
CHANGED
@@ -1,30 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "lib/identifiable/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.version = Identifiable::VERSION
|
7
|
-
spec.name =
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
7
|
+
spec.name = "identifiable"
|
8
|
+
spec.authors = ["Tom Pritchard"]
|
9
|
+
spec.email = ["tom@tpritc.com"]
|
10
10
|
|
11
|
-
spec.summary =
|
12
|
-
spec.homepage =
|
13
|
-
spec.license =
|
14
|
-
spec.required_ruby_version =
|
11
|
+
spec.summary = "A quick and easy way to add random, customizable, public-facing IDs to your models."
|
12
|
+
spec.homepage = "https://github.com/tpritc/identifiable"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = ">= 3.2.0"
|
15
15
|
|
16
16
|
# Specify which files should be added to the gem when it is released.
|
17
17
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
18
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
19
19
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
20
|
end
|
21
|
-
spec.bindir =
|
21
|
+
spec.bindir = "exe"
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
-
spec.require_paths = [
|
23
|
+
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
25
|
+
spec.add_dependency "activerecord", "> 7"
|
26
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
spec.add_development_dependency "rubocop", "~> 1.3"
|
29
|
+
spec.add_development_dependency "sqlite3"
|
30
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
30
31
|
end
|
data/lib/identifiable/errors.rb
CHANGED
@@ -4,7 +4,7 @@ module Identifiable
|
|
4
4
|
module Errors
|
5
5
|
class ColumnMustBeASymbolError < StandardError
|
6
6
|
def initialize(column_value)
|
7
|
-
column_value_string = column_value.to_s
|
7
|
+
column_value_string = column_value.to_s
|
8
8
|
column_value_class = column_value.class.to_s
|
9
9
|
super("The identifiable's column must be a symbol. You passed in #{column_value_string}, which was a #{column_value_class}.")
|
10
10
|
end
|
@@ -12,51 +12,51 @@ module Identifiable
|
|
12
12
|
|
13
13
|
class ColumnCannotBeIdError < StandardError
|
14
14
|
def initialize
|
15
|
-
super(
|
15
|
+
super("The identifiable's column cannot be :id, since that's your primary key. You should create another index column in your table with a name like :public_id.")
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
class ColumnMustExistInTheTableError < StandardError
|
20
20
|
def initialize(column_value, valid_columns:)
|
21
|
-
column_value_string = column_value.to_s
|
21
|
+
column_value_string = column_value.to_s
|
22
22
|
super("The identifiable's column must exist on the table for this model. You passed in #{column_value_string}, but the valid columns are: #{valid_columns}")
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
class StyleMustBeAValidStyleError < StandardError
|
27
27
|
def initialize(style_value)
|
28
|
-
style_value_string = style_value.to_s
|
29
|
-
super("The identifiable
|
28
|
+
style_value_string = style_value.to_s
|
29
|
+
super("The identifiable's style must be a valid stylist. You passed in #{style_value_string}, but the valid options are: #{Identifiable::Stylist::VALID_STYLES}")
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
class LengthMustBeAnIntegerError < StandardError
|
34
34
|
def initialize
|
35
|
-
super(
|
35
|
+
super("The identifiable's length must be an Integer.")
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
class LengthIsTooShortError < StandardError
|
40
40
|
def initialize
|
41
|
-
super(
|
41
|
+
super("The identifiable's length must be at least 4.")
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
45
|
class LengthIsTooLongError < StandardError
|
46
46
|
def initialize
|
47
|
-
super(
|
47
|
+
super("The identifiable's length cannot be more than 128.")
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
class LengthMustBeNilIfStyleIsUuidError < StandardError
|
52
52
|
def initialize
|
53
|
-
super(
|
53
|
+
super("The identifiable's length cannot be set if you're using the :uuid style, because UUIDs have a fixed length. You should remove the length parameter.")
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
57
|
class RanOutOfAttemptsToSetPublicIdError < StandardError
|
58
58
|
def initialize
|
59
|
-
super(
|
59
|
+
super("We tried 100 times to find an unused public ID, but we could not find one. You should increase the length parameter of the public ID.")
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
data/lib/identifiable/model.rb
CHANGED
@@ -25,7 +25,7 @@ module Identifiable
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def find_by_public_id(public_id)
|
28
|
-
where(
|
28
|
+
where({ identifiable_column => public_id }).first
|
29
29
|
end
|
30
30
|
|
31
31
|
def find_by_public_id!(public_id)
|
@@ -54,11 +54,17 @@ module Identifiable
|
|
54
54
|
# The column parameter must be in the model's table, so check that the
|
55
55
|
# column corresponds to a column in the model's table, and raise an error
|
56
56
|
# if it is not.
|
57
|
+
#
|
58
|
+
# We suppress ActiveRecord::StatmentInvalid errors just in case the table
|
59
|
+
# does not exist yet.
|
60
|
+
# rubocop:disable Lint/SuppressedException
|
57
61
|
def _identifiable_validate_column_must_be_in_the_table
|
58
62
|
return if column_names.include? @identifiable_column.to_s
|
59
63
|
|
60
64
|
raise Identifiable::Errors::ColumnMustExistInTheTableError.new(@identifiable_column, valid_columns: column_names)
|
65
|
+
rescue ActiveRecord::StatementInvalid
|
61
66
|
end
|
67
|
+
# rubocop:enable Lint/SuppressedException
|
62
68
|
|
63
69
|
# We can only use valid styles, so check that the style parameter is a
|
64
70
|
# valid style, and raise an error if it is not.
|
@@ -114,5 +120,23 @@ module Identifiable
|
|
114
120
|
# If we got this far, we've got a new valid public ID, time to set it!
|
115
121
|
self[self.class.identifiable_column] = new_public_id
|
116
122
|
end
|
123
|
+
|
124
|
+
# By overriding ActiveRecord's `#to_key`, this means that Rails' helpers,
|
125
|
+
# such as `dom_id` will use the public ID instead of the regular ID when
|
126
|
+
# identifying the record.
|
127
|
+
def to_key
|
128
|
+
return super unless Identifiable.configuration.overwrite_to_key
|
129
|
+
|
130
|
+
[self[self.class.identifiable_column]]
|
131
|
+
end
|
132
|
+
|
133
|
+
# By overriding ActiveRecord's `#to_param`, this means that Rails' helpers,
|
134
|
+
# such as the `link_to` helpers will default to using the public ID
|
135
|
+
# instead of the regular ID when identifying the record.
|
136
|
+
def to_param
|
137
|
+
return super unless Identifiable.configuration.overwrite_to_param
|
138
|
+
|
139
|
+
self[self.class.identifiable_column]
|
140
|
+
end
|
117
141
|
end
|
118
142
|
end
|
data/lib/identifiable/version.rb
CHANGED
data/lib/identifiable.rb
CHANGED
@@ -3,15 +3,26 @@
|
|
3
3
|
module Identifiable
|
4
4
|
module Stylists
|
5
5
|
end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def configuration
|
9
|
+
@configuration ||= Configuration.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure
|
13
|
+
yield(configuration)
|
14
|
+
end
|
15
|
+
end
|
6
16
|
end
|
7
17
|
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
18
|
+
require "active_record"
|
19
|
+
require "identifiable/configuration"
|
20
|
+
require "identifiable/stylist"
|
21
|
+
require "identifiable/stylists/alphanumeric"
|
22
|
+
require "identifiable/stylists/numeric"
|
23
|
+
require "identifiable/stylists/uuid"
|
24
|
+
require "identifiable/errors"
|
25
|
+
require "identifiable/model"
|
26
|
+
require "identifiable/version"
|
16
27
|
|
17
28
|
ActiveRecord::Base.include Identifiable::Model
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: identifiable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Pritchard
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '7'
|
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: '
|
26
|
+
version: '7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,7 +82,7 @@ dependencies:
|
|
82
82
|
version: '0'
|
83
83
|
description:
|
84
84
|
email:
|
85
|
-
-
|
85
|
+
- tom@tpritc.com
|
86
86
|
executables: []
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- ".rspec"
|
93
93
|
- ".rubocop.yml"
|
94
94
|
- ".tool-versions"
|
95
|
+
- CHANGELOG.md
|
95
96
|
- CODE_OF_CONDUCT.md
|
96
97
|
- Gemfile
|
97
98
|
- Gemfile.lock
|
@@ -99,9 +100,12 @@ files:
|
|
99
100
|
- README.md
|
100
101
|
- Rakefile
|
101
102
|
- bin/console
|
103
|
+
- bin/rspec
|
104
|
+
- bin/rubocop
|
102
105
|
- bin/setup
|
103
106
|
- identifiable.gemspec
|
104
107
|
- lib/identifiable.rb
|
108
|
+
- lib/identifiable/configuration.rb
|
105
109
|
- lib/identifiable/errors.rb
|
106
110
|
- lib/identifiable/model.rb
|
107
111
|
- lib/identifiable/stylist.rb
|
@@ -112,7 +116,8 @@ files:
|
|
112
116
|
homepage: https://github.com/tpritc/identifiable
|
113
117
|
licenses:
|
114
118
|
- MIT
|
115
|
-
metadata:
|
119
|
+
metadata:
|
120
|
+
rubygems_mfa_required: 'true'
|
116
121
|
post_install_message:
|
117
122
|
rdoc_options: []
|
118
123
|
require_paths:
|
@@ -121,14 +126,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
126
|
requirements:
|
122
127
|
- - ">="
|
123
128
|
- !ruby/object:Gem::Version
|
124
|
-
version: 2.
|
129
|
+
version: 3.2.0
|
125
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
131
|
requirements:
|
127
132
|
- - ">="
|
128
133
|
- !ruby/object:Gem::Version
|
129
134
|
version: '0'
|
130
135
|
requirements: []
|
131
|
-
rubygems_version: 3.1
|
136
|
+
rubygems_version: 3.4.1
|
132
137
|
signing_key:
|
133
138
|
specification_version: 4
|
134
139
|
summary: A quick and easy way to add random, customizable, public-facing IDs to your
|