encoded_id-rails 1.0.0.beta3 → 1.0.0.rc1

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
  SHA256:
3
- metadata.gz: 3a38e6af88bf9343e2e4d22a82eb4c4d87766e962f3a8d330bf6aad1ad374639
4
- data.tar.gz: 3ea6b28d604d3f728da545d324f50b12845f2feb9b7ed83c32349e002cdb6c93
3
+ metadata.gz: 67437c2f5ede5d3d8a7ff14079ce9518b1e63a48812fd37a88d61772fa1d0ea3
4
+ data.tar.gz: 59f73a3eb40b421bdf50115f806cbf5cd41b09213ebe87ce4d1842b098530f47
5
5
  SHA512:
6
- metadata.gz: b03bc14efe460f8f479f109d32a4197c88cc85b72d87b7aa348e40057c4ae540728f5f3c383b943460ebbfdcfdd7e3173c363dbb423026386331fe17ea7e50e8
7
- data.tar.gz: 5a6f16dc29c1c43450f278e08b7c82e597e13a70b4ea5183cbcc97d690307c6b847b5fef8cd594cb0f1396aca685beac78a8c427826b2003a1b2820b319793a3
6
+ metadata.gz: c8f03e548c344e45343ad831b568eedf705c02db9da876445a67d8814d9d4efd37d0ae639bf7eb6a1fd33685d68bc01077a523addffa319c9022cfd534771de7
7
+ data.tar.gz: 0037b79f44ce1ddeb97bc142e11c35b045c446db1b87e7122eeceb06bb606499a60764c3ab85593d352f0be39b074cf72805078d511bce80c53cd3ba745372b5
@@ -0,0 +1,17 @@
1
+ # Make sure RUBY_VERSION matches the Ruby version in .ruby-version or gemspec
2
+ ARG RUBY_VERSION=3.4.2
3
+ FROM ghcr.io/rails/devcontainer/images/ruby:$RUBY_VERSION
4
+
5
+ USER root
6
+
7
+ # Install pkg-config and SQLite development libraries
8
+ RUN apt-get update -qq && \
9
+ apt-get install -y pkg-config libsqlite3-dev && \
10
+ apt-get clean && \
11
+ rm -rf /var/lib/apt/lists/*
12
+
13
+ USER vscode
14
+
15
+ # Ensure binding is always 0.0.0.0
16
+ # Binds the server to all IP addresses of the container, so it can be accessed from outside the container.
17
+ ENV BINDING="0.0.0.0"
@@ -0,0 +1,10 @@
1
+ name: "encoded_id-rails"
2
+
3
+ services:
4
+ encoded-id-rails-dev-env:
5
+ container_name: encoded-id-rails-dev-env
6
+ build:
7
+ context: ..
8
+ dockerfile: .devcontainer/Dockerfile
9
+ ports:
10
+ - "3000"
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "Encoded ID Rails Gem Development",
3
+ "dockerComposeFile": "compose.yml",
4
+ "service": "encoded-id-rails-dev-env",
5
+ "containerEnv": {
6
+ "RAILS_ENV": "development"
7
+ },
8
+ "forwardPorts": [3000],
9
+ "postCreateCommand": "bundle install && bundle exec appraisal install",
10
+ "postStartCommand": "bundle exec rake test",
11
+ "remoteUser": "vscode"
12
+ }
data/Appraisals CHANGED
@@ -1,14 +1,9 @@
1
- appraise "rails-6.1" do
2
- gem "activesupport", "~> 6.1.7", ">= 6.1.0"
3
- gem "activerecord", "~> 6.1.7", ">= 6.1.0"
1
+ appraise "rails-7.2" do
2
+ gem "activesupport", "~> 7.2.0"
3
+ gem "activerecord", "~> 7.2.0"
4
4
  end
5
5
 
6
- appraise "rails-7.0" do
7
- gem "activesupport", "~> 7.0.4"
8
- gem "activerecord", "~> 7.0.4"
9
- end
10
-
11
- appraise "rails-7.1" do
12
- gem "activesupport", "~> 7.1"
13
- gem "activerecord", "~> 7.1"
6
+ appraise "rails-8.0" do
7
+ gem "activesupport", "~> 8.0.0"
8
+ gem "activerecord", "~> 8.0.0"
14
9
  end
data/Gemfile CHANGED
@@ -14,5 +14,11 @@ group :development, :test do
14
14
 
15
15
  gem "steep", "~> 1.5"
16
16
 
17
- gem "sqlite3", "~> 1.5"
17
+ gem "rails"
18
+
19
+ gem "sqlite3"
20
+
21
+ gem "appraisal"
22
+
23
+ gem "simplecov"
18
24
  end
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `EncodedId::Rails` lets you turn numeric or hex **IDs into reversible and human friendly obfuscated strings**. The gem brings [EncodedId](https://github.com/stevegeek/encoded_id) to Rails and `ActiveRecord` models.
4
4
 
5
- You can use it in routes for example, to go from something like `/users/725` to `/users/bob-smith--usr_p5w9-z27j` with miminal effort.
5
+ You can use it in routes for example, to go from something like `/users/725` to `/users/bob-smith--usr_p5w9-z27j` with minimal effort.
6
6
 
7
7
  ## Features
8
8
 
@@ -17,7 +17,7 @@ Under the hood it uses hashIds, but it offers more features.
17
17
  - by default uses a variation of the Crockford reduced character set (https://www.crockford.com/base32.html)
18
18
  - easily confused characters (eg i and j, 0 and O, 1 and I etc) are mapped to counterpart characters, to
19
19
  help avoid common readability mistakes when reading/sharing
20
- - build in profanity limitation
20
+ - built-in profanity limitation
21
21
 
22
22
  The gem provides:
23
23
 
@@ -69,7 +69,6 @@ when sharing encoded IDs with other people.
69
69
  * the gem is configurable
70
70
  * encoded IDs can be stable across environments, or not (you can set the salt to different values per environment)
71
71
 
72
-
73
72
  ## Coming in future (?)
74
73
 
75
74
  - support for UUIDs for IDs (which will be encoded as an array of integers)
@@ -87,6 +86,12 @@ If bundler is not being used to manage dependencies, install the gem by executin
87
86
  Then run the generator to add the initializer:
88
87
 
89
88
  rails g encoded_id:rails:install
89
+
90
+ If you plan to use the `EncodedId::Rails::Persists` module to persist encoded IDs, you can generate the necessary migration:
91
+
92
+ rails g encoded_id:rails:add_columns User Product # Add to multiple models
93
+
94
+ This will create a migration that adds the required columns and indexes to the specified models.
90
95
 
91
96
  ## Usage
92
97
 
@@ -102,6 +107,7 @@ You can configure:
102
107
  - the separator between the character groups (default is '-')
103
108
  - the alphabet used to generate the encoded string (default is a variation of the Crockford reduced character set)
104
109
  - the minimum length of the encoded ID string (default is 8 characters)
110
+ - whether models automatically override `to_param` to return the encoded ID (default is false)
105
111
 
106
112
  ### ActiveRecord model setup
107
113
 
@@ -124,8 +130,8 @@ end
124
130
 
125
131
  You can optionally include one of the following mixins to add default overrides to `#to_param`.
126
132
 
127
- - `EncodedId::PathParam`
128
- - `EncodedId::SluggedPathParam`
133
+ - `EncodedId::PathParam` - Makes `to_param` return the encoded ID
134
+ - `EncodedId::SluggedPathParam` - Makes `to_param` return the slugged encoded ID
129
135
 
130
136
  This is so that an instance of the model can be used in path helpers and
131
137
  return the encoded ID string instead of the record ID by default.
@@ -144,6 +150,89 @@ user = User.create(full_name: "Bob Smith")
144
150
  Rails.application.routes.url_helpers.user_path(user) # => "/users/bob-smith--p5w9-z27j"
145
151
  ```
146
152
 
153
+ Alternatively, you can configure the gem to automatically override `to_param` for all models that include `EncodedId::Model` by setting the `model_to_param_returns_encoded_id` configuration option to `true`:
154
+
155
+ ```ruby
156
+ # In config/initializers/encoded_id.rb
157
+ EncodedId::Rails.configure do |config|
158
+ # ... other configuration options
159
+ config.model_to_param_returns_encoded_id = true
160
+ end
161
+
162
+ # Then in your model
163
+ class User < ApplicationRecord
164
+ include EncodedId::Model # to_param will automatically return encoded_id
165
+ end
166
+
167
+ user = User.create(name: "Bob Smith")
168
+ Rails.application.routes.url_helpers.user_path(user) # => "/users/user_p5w9-z27j"
169
+ ```
170
+
171
+ With this configuration, all models will behave as if they included `EncodedId::PathParam`.
172
+
173
+ ### Persisting encoded IDs
174
+
175
+ You can optionally include the `EncodedId::Rails::Persists` mixin to persist the encoded ID in the database. This allows you to query directly by encoded ID in the database and enables more efficient lookups.
176
+
177
+ To use this feature, you can either:
178
+
179
+ 1. Use the generator to create a migration for your models:
180
+
181
+ ```bash
182
+ rails g encoded_id:rails:add_columns User Product
183
+ ```
184
+
185
+ 2. Or manually add the following columns to your model's table:
186
+
187
+ ```ruby
188
+ add_column :users, :normalized_encoded_id, :string
189
+ add_column :users, :prefixed_encoded_id, :string
190
+ add_index :users, :normalized_encoded_id, unique: true
191
+ add_index :users, :prefixed_encoded_id, unique: true
192
+ ```
193
+
194
+ Then include the mixin in your model:
195
+
196
+ ```ruby
197
+ class User < ApplicationRecord
198
+ include EncodedId::Model
199
+ include EncodedId::Rails::Persists
200
+ end
201
+ ```
202
+
203
+ The mixin will:
204
+
205
+ 1. Store the encoded ID hash (without character grouping) in the `normalized_encoded_id` column
206
+ 2. Store the complete encoded ID (with prefix if any) in the `prefixed_encoded_id` column
207
+ 3. Add validations to ensure these columns are unique
208
+ 4. Make these columns readonly after creation
209
+ 5. Automatically update the persisted encoded IDs when the record is created
210
+ 6. Ensure encoded IDs are reset when a record is duplicated
211
+ 7. Provide safeguards to prevent inconsistencies
212
+
213
+ This enables direct database queries by encoded ID without having to decode them first. It also allows you to create database indexes on these columns for more efficient lookups.
214
+
215
+ #### Example Usage of Persisted Encoded IDs
216
+
217
+ Once you've set up the necessary database columns and included the `Persists` module, you can use the persisted encoded IDs:
218
+
219
+ ```ruby
220
+ # Creating a record automatically sets the encoded IDs
221
+ user = User.create(name: "Bob Smith")
222
+ user.normalized_encoded_id # => "p5w9z27j" (encoded ID without character grouping)
223
+ user.prefixed_encoded_id # => "user_p5w9-z27j" (complete encoded ID with prefix)
224
+
225
+ # You can use these in ActiveRecord queries now of course, eg
226
+ User.where(normalized_encoded_id: ["p5w9z27j", "7aq60zqw"])
227
+
228
+ # If you need to refresh the encoded ID (e.g., you changed the salt)
229
+ user.set_normalized_encoded_id!
230
+
231
+ # The module protects against direct changes to these attributes
232
+ user.normalized_encoded_id = "something-else"
233
+ user.save # This will raise ActiveRecord::ReadonlyAttributeError
234
+ ```
235
+
147
236
  ## Documentation
148
237
 
149
238
  ### `.find_by_encoded_id`
@@ -185,7 +274,7 @@ this method will return an array of records.
185
274
  A helper for creating relations. Decodes the encoded ID string before passing it to `.where`.
186
275
 
187
276
  ```ruby
188
- encoded_id = User.encode_encoded_id([user1.id, user2.id]) # => "p5w9-z27j"
277
+ encoded_id = User.encode_encoded_id([user1.id, user2.id]) # => "7aq6-0zqw"
189
278
  User.where(active: true)
190
279
  .where_encoded_id(encoded_id)
191
280
  .map(&:name) # => ["Bob Smith", "Jane Doe"]
@@ -234,11 +323,11 @@ User.encoded_id_salt # => "my-user-model-salt"
234
323
 
235
324
  ### `#encoded_id_hash`
236
325
 
237
- Returns only the encoded 'hashId' part of the encoded ID for the record:
326
+ Returns only the encoded 'hashId' part of the encoded ID for the record (without any annotation):
238
327
 
239
328
  ```ruby
240
329
  user = User.create(name: "Bob Smith")
241
- user.encoded_id # => "p5w9-z27j"
330
+ user.encoded_id_hash # => "p5w9-z27j"
242
331
  ```
243
332
 
244
333
 
@@ -344,8 +433,8 @@ Note that you can also configure the slug separator via the `slugged_id_separato
344
433
  but it must be set to a string that only contains character that are not part of the alphabet used to encode the ID.
345
434
 
346
435
  ```ruby
347
- EncodedId::Rails.configuration.annotated_id_separator = "***"
348
- user.encoded_id # => "bob-smith***p5w9-z27j"
436
+ EncodedId::Rails.configuration.slugged_id_separator = "***"
437
+ user.slugged_encoded_id # => "bob-smith***p5w9-z27j"
349
438
  ```
350
439
 
351
440
  ## To use on all models
@@ -391,10 +480,33 @@ end
391
480
  <%= link_to "User", user_path %>
392
481
  ```
393
482
 
483
+ ## Performance Considerations
484
+
485
+ The performance of encoding and decoding IDs depends on several factors:
486
+
487
+ 1. **ID Length**: The longer the minimum ID length specified in configuration (`id_length`), the slower the encoding and decoding process will be. This is because the underlying Hashids algorithm has to do more work to generate longer IDs. If performance is critical, consider using shorter ID lengths, but be aware of the security tradeoffs.
488
+
489
+ 2. **Encoding Multiple IDs**: Encoding multiple IDs in a single string is more computationally expensive than encoding a single ID.
490
+
491
+ 3. **Database Queries**: When using `find_by_encoded_id` or `where_encoded_id`, each lookup requires decoding first. Consider using the `Persists` module to store encoded IDs if this is an issue.
492
+
493
+ 4. **Character Grouping**: Using character grouping with separators adds a small overhead to encoding and decoding.
494
+
495
+ For detailed performance metrics and benchmarks, refer to the [EncodedId gem documentation](https://github.com/stevegeek/encoded_id).
496
+
497
+
394
498
  ## Development
395
499
 
396
500
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
397
501
 
502
+ To run tests with code coverage:
503
+
504
+ ```bash
505
+ bundle exec rake coverage
506
+ ```
507
+
508
+ This will generate a coverage report in the `coverage` directory that you can open in your browser.
509
+
398
510
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
399
511
 
400
512
  ### Type check
data/Rakefile CHANGED
@@ -6,7 +6,13 @@ require "rake/testtask"
6
6
  Rake::TestTask.new(:test) do |t|
7
7
  t.libs << "test"
8
8
  t.libs << "lib"
9
- t.test_files = FileList["test/**/test_*.rb"]
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ end
11
+
12
+ desc "Run tests with coverage"
13
+ task :coverage do
14
+ ENV["COVERAGE"] = "true"
15
+ Rake::Task["test"].invoke
10
16
  end
11
17
 
12
18
  require "standard/rake"
@@ -2,15 +2,18 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activesupport", "~> 6.1.7", ">= 6.1.0"
6
- gem "activerecord", "~> 6.1.7", ">= 6.1.0"
5
+ gem "activesupport", "~> 7.2.0"
6
+ gem "activerecord", "~> 7.2.0"
7
7
 
8
8
  group :development, :test do
9
9
  gem "rake", "~> 13.0"
10
10
  gem "minitest", "~> 5.0"
11
11
  gem "standard", "~> 1.30"
12
12
  gem "steep", "~> 1.5"
13
- gem "sqlite3", "~> 1.5"
13
+ gem "rails"
14
+ gem "sqlite3"
15
+ gem "appraisal"
16
+ gem "simplecov"
14
17
  end
15
18
 
16
19
  gemspec path: "../"
@@ -2,15 +2,18 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activesupport", "~> 7.1"
6
- gem "activerecord", "~> 7.1"
5
+ gem "activesupport", "~> 8.0.0"
6
+ gem "activerecord", "~> 8.0.0"
7
7
 
8
8
  group :development, :test do
9
9
  gem "rake", "~> 13.0"
10
10
  gem "minitest", "~> 5.0"
11
11
  gem "standard", "~> 1.30"
12
12
  gem "steep", "~> 1.5"
13
- gem "sqlite3", "~> 1.5"
13
+ gem "rails"
14
+ gem "sqlite3"
15
+ gem "appraisal"
16
+ gem "simplecov"
14
17
  end
15
18
 
16
19
  gemspec path: "../"
@@ -6,6 +6,7 @@ module EncodedId
6
6
  class Configuration
7
7
  attr_accessor :salt, :character_group_size, :alphabet, :id_length
8
8
  attr_accessor :slug_value_method_name, :annotation_method_name
9
+ attr_accessor :model_to_param_returns_encoded_id
9
10
  attr_reader :group_separator, :slugged_id_separator, :annotated_id_separator
10
11
 
11
12
  def initialize
@@ -17,6 +18,7 @@ module EncodedId
17
18
  @slugged_id_separator = "--"
18
19
  @annotation_method_name = :annotation_for_encoded_id
19
20
  @annotated_id_separator = "_"
21
+ @model_to_param_returns_encoded_id = false
20
22
  end
21
23
 
22
24
  # Perform validation vs alphabet on these assignments
@@ -10,34 +10,69 @@ module EncodedId
10
10
  base.extend(EncoderMethods)
11
11
  base.extend(FinderMethods)
12
12
  base.extend(QueryMethods)
13
+
14
+ # Automatically include PathParam if configured to do so
15
+ if EncodedId::Rails.configuration.model_to_param_returns_encoded_id
16
+ base.include(EncodedId::Rails::PathParam)
17
+ end
18
+ end
19
+
20
+ attr_accessor :encoded_id_memoized_with_id
21
+
22
+ def clear_encoded_id_cache!
23
+ [:@encoded_id_hash, :@encoded_id, :@slugged_encoded_id].each do |var|
24
+ remove_instance_variable(var) if instance_variable_defined?(var)
25
+ end
26
+ self.encoded_id_memoized_with_id = nil
27
+ end
28
+
29
+ def check_and_clear_memoization
30
+ clear_encoded_id_cache! if encoded_id_memoized_with_id && encoded_id_memoized_with_id != id
13
31
  end
14
32
 
15
33
  def encoded_id_hash
16
34
  return unless id
17
- return @encoded_id_hash if defined?(@encoded_id_hash) && !id_changed?
18
- self.class.encode_encoded_id(id)
35
+ check_and_clear_memoization
36
+ return @encoded_id_hash if defined?(@encoded_id_hash)
37
+
38
+ self.encoded_id_memoized_with_id = id
39
+ @encoded_id_hash = self.class.encode_encoded_id(id)
19
40
  end
20
41
 
21
42
  def encoded_id
22
43
  return unless id
23
- return @encoded_id if defined?(@encoded_id) && !id_changed?
44
+ check_and_clear_memoization
45
+ return @encoded_id if defined?(@encoded_id)
46
+
24
47
  encoded = encoded_id_hash
25
48
  annotated_by = EncodedId::Rails.configuration.annotation_method_name
26
49
  return @encoded_id = encoded unless annotated_by && encoded
50
+
27
51
  separator = EncodedId::Rails.configuration.annotated_id_separator
52
+ self.encoded_id_memoized_with_id = id
28
53
  @encoded_id = EncodedId::Rails::AnnotatedId.new(id_part: encoded, annotation: send(annotated_by.to_s), separator: separator).annotated_id
29
54
  end
30
55
 
31
56
  def slugged_encoded_id
32
57
  return unless id
33
- return @slugged_encoded_id if defined?(@slugged_encoded_id) && !id_changed?
58
+ check_and_clear_memoization
59
+ return @slugged_encoded_id if defined?(@slugged_encoded_id)
60
+
34
61
  with = EncodedId::Rails.configuration.slug_value_method_name
35
62
  separator = EncodedId::Rails.configuration.slugged_id_separator
36
63
  encoded = encoded_id
37
64
  return unless encoded
65
+
66
+ self.encoded_id_memoized_with_id = id
38
67
  @slugged_encoded_id = EncodedId::Rails::SluggedId.new(id_part: encoded, slug_part: send(with.to_s), separator: separator).slugged_id
39
68
  end
40
69
 
70
+ def reload(options = nil)
71
+ result = super
72
+ clear_encoded_id_cache!
73
+ result
74
+ end
75
+
41
76
  # By default the annotation is the model name (it will be parameterized)
42
77
  def annotation_for_encoded_id
43
78
  name = self.class.name
@@ -52,11 +87,10 @@ module EncodedId
52
87
  raise StandardError, "You must define a method to generate the slug for the encoded ID of #{self.class.name}"
53
88
  end
54
89
 
55
- # When duplicating an ActiveRecord object, we want to reset the memoized encoded_id
90
+ # When duplicating an ActiveRecord object, we want to reset the memoized encoded IDs
56
91
  def dup
57
92
  super.tap do |new_record|
58
- new_record.send(:remove_instance_variable, :@encoded_id) if new_record.instance_variable_defined?(:@encoded_id)
59
- new_record.send(:remove_instance_variable, :@slugged_encoded_id) if new_record.instance_variable_defined?(:@slugged_encoded_id)
93
+ new_record.clear_encoded_id_cache!
60
94
  end
61
95
  end
62
96
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EncodedId
4
+ module Rails
5
+ module Persists
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+
9
+ base.validates :normalized_encoded_id, uniqueness: true, allow_nil: true
10
+ base.validates :prefixed_encoded_id, uniqueness: true, allow_nil: true
11
+
12
+ base.before_validation :prevent_update_of_normalized_encoded_id!, if: :normalized_encoded_id_changed?
13
+ base.before_validation :prevent_update_of_prefixed_encoded_id!, if: :prefixed_encoded_id_changed?
14
+
15
+ base.after_create :set_normalized_encoded_id!
16
+ base.before_save :update_normalized_encoded_id!, if: :should_update_normalized_encoded_id?
17
+
18
+ base.after_commit :check_encoded_id_persisted!, on: [:create, :update]
19
+ end
20
+
21
+ module ClassMethods
22
+ def encode_normalized_encoded_id(id)
23
+ encode_encoded_id(id, character_group_size: nil)
24
+ end
25
+ end
26
+
27
+ # On duplication we need to reset the encoded ID to nil as this new record will have a new ID.
28
+ # We need to also prevent these changes from marking the record as dirty.
29
+ def dup
30
+ copy = super
31
+ copy.prefixed_encoded_id = nil
32
+ copy.clear_prefixed_encoded_id_change
33
+ copy.normalized_encoded_id = nil
34
+ copy.clear_normalized_encoded_id_change
35
+ copy
36
+ end
37
+
38
+ def set_normalized_encoded_id!
39
+ validate_id_for_encoded_id!
40
+
41
+ update_columns(normalized_encoded_id: self.class.encode_normalized_encoded_id(id), prefixed_encoded_id: encoded_id)
42
+ end
43
+
44
+ def update_normalized_encoded_id!
45
+ validate_id_for_encoded_id!
46
+
47
+ self.normalized_encoded_id = self.class.encode_normalized_encoded_id(id)
48
+ self.prefixed_encoded_id = encoded_id
49
+ end
50
+
51
+ def check_encoded_id_persisted!
52
+ if normalized_encoded_id != self.class.encode_normalized_encoded_id(id)
53
+ raise StandardError, "The persisted encoded ID #{normalized_encoded_id} for #{self.class.name} is not the same as currently computing #{self.class.encode_normalized_encoded_id(id)}"
54
+ end
55
+
56
+ raise StandardError, "The persisted prefixed encoded ID (for #{self.class.name} with id: #{id}, normalized_encoded_id: #{normalized_encoded_id}) is not correct: it is #{prefixed_encoded_id} instead of #{encoded_id}" if prefixed_encoded_id != encoded_id
57
+ end
58
+
59
+ def should_update_normalized_encoded_id?
60
+ id_changed? || (normalized_encoded_id.blank? && persisted?)
61
+ end
62
+
63
+ def validate_id_for_encoded_id!
64
+ raise StandardError, "You cannot set the normalized ID of a record which is not persisted" if id.blank?
65
+ end
66
+
67
+ def prevent_update_of_normalized_encoded_id!
68
+ raise ActiveRecord::ReadonlyAttributeError, "You cannot update the normalized encoded ID '#{normalized_encoded_id}' of a record #{self.class.name} #{id}, if you need to refresh it use set_normalized_encoded_id!"
69
+ end
70
+
71
+ def prevent_update_of_prefixed_encoded_id!
72
+ raise ActiveRecord::ReadonlyAttributeError, "You cannot update the prefixed encoded ID '#{prefixed_encoded_id}' of a record #{self.class.name} #{id}, if you need to refresh it use set_normalized_encoded_id!"
73
+ end
74
+ end
75
+ end
76
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module EncodedId
4
4
  module Rails
5
- VERSION = "1.0.0.beta3"
5
+ VERSION = "1.0.0.rc1"
6
6
  end
7
7
  end
@@ -14,6 +14,7 @@ require_relative "rails/finder_methods"
14
14
  require_relative "rails/path_param"
15
15
  require_relative "rails/slugged_path_param"
16
16
  require_relative "rails/model"
17
+ require_relative "rails/persists"
17
18
 
18
19
  module EncodedId
19
20
  module Rails
@@ -1,3 +1,7 @@
1
1
  Creates an initialiser:
2
2
 
3
3
  rails generate encoded_id:rails:install
4
+
5
+ Creates migrations for persisting encoded IDs:
6
+
7
+ rails generate encoded_id:rails:add_columns Model [Model2 Model3 ...]
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/active_record/migration"
4
+
5
+ module EncodedId
6
+ module Rails
7
+ module Generators
8
+ # Generator for adding encoded ID columns to models
9
+ # Usage: rails generate encoded_id:rails:add_columns Model [Model2 Model3 ...]
10
+ class AddColumnsGenerator < ::Rails::Generators::Base
11
+ include ::ActiveRecord::Generators::Migration
12
+
13
+ source_root File.expand_path(__dir__)
14
+
15
+ argument :model_names, type: :array, desc: "Model name or names to add columns to"
16
+
17
+ desc "Adds encoded_id persistence columns to the specified models"
18
+
19
+ def create_migration_file
20
+ migration_template(
21
+ "templates/add_encoded_id_columns_migration.rb.erb",
22
+ "db/migrate/add_encoded_id_columns_to_#{table_names}.rb",
23
+ migration_version: migration_version
24
+ )
25
+ end
26
+
27
+ private
28
+
29
+ def table_names
30
+ @table_names ||= model_names.map do |model_name|
31
+ model_name.underscore.pluralize
32
+ end.join("_and_")
33
+ end
34
+
35
+ def migration_version
36
+ "[#{::ActiveRecord::VERSION::MAJOR}.#{::ActiveRecord::VERSION::MINOR}]"
37
+ end
38
+
39
+ def migration_class_name
40
+ "AddEncodedIdColumnsTo#{table_names.camelize}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
4
+ def change
5
+ <% model_names.each do |model_name| %>
6
+ # Get table name from the model or infer from model name
7
+ table_name = :<%= model_name.underscore.pluralize %>
8
+
9
+ add_column table_name, :normalized_encoded_id, :string
10
+ add_column table_name, :prefixed_encoded_id, :string
11
+
12
+ add_index table_name, :normalized_encoded_id, unique: true
13
+ add_index table_name, :prefixed_encoded_id, unique: true
14
+ <% end %>
15
+ end
16
+ end
@@ -67,4 +67,12 @@ EncodedId::Rails.configure do |config|
67
67
  # Default: "_"
68
68
  #
69
69
  # config.annotated_id_separator = "_"
70
+
71
+ # When true, models that include EncodedId::Model will automatically have their to_param method
72
+ # return the encoded ID (equivalent to also including EncodedId::Rails::PathParam).
73
+ # This makes any model with EncodedId::Model automatically use encoded IDs in URLs.
74
+ #
75
+ # Default: false
76
+ #
77
+ # config.model_to_param_returns_encoded_id = true
70
78
  end
@@ -8,7 +8,7 @@ module EncodedId
8
8
  attr_accessor character_group_size: ::Integer
9
9
  attr_accessor alphabet: ::EncodedId::Alphabet
10
10
  attr_accessor id_length: ::Integer
11
- attr_accessor slug_value_method_name: ::Symbol
11
+ attr_accessor slug_method_name: ::Symbol
12
12
  attr_accessor slugged_id_separator: ::String
13
13
  attr_accessor annotation_method_name: ::Symbol
14
14
  attr_accessor annotated_id_separator: ::String
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: encoded_id-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta3
4
+ version: 1.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Ierodiaconou
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-04-29 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -16,68 +15,54 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '6.0'
18
+ version: '7.2'
20
19
  - - "<"
21
20
  - !ruby/object:Gem::Version
22
- version: '8.0'
21
+ version: '9'
23
22
  type: :runtime
24
23
  prerelease: false
25
24
  version_requirements: !ruby/object:Gem::Requirement
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- version: '6.0'
28
+ version: '7.2'
30
29
  - - "<"
31
30
  - !ruby/object:Gem::Version
32
- version: '8.0'
31
+ version: '9'
33
32
  - !ruby/object:Gem::Dependency
34
33
  name: activerecord
35
34
  requirement: !ruby/object:Gem::Requirement
36
35
  requirements:
37
36
  - - ">="
38
37
  - !ruby/object:Gem::Version
39
- version: '6.0'
38
+ version: '7.2'
40
39
  - - "<"
41
40
  - !ruby/object:Gem::Version
42
- version: '8.0'
41
+ version: '9'
43
42
  type: :runtime
44
43
  prerelease: false
45
44
  version_requirements: !ruby/object:Gem::Requirement
46
45
  requirements:
47
46
  - - ">="
48
47
  - !ruby/object:Gem::Version
49
- version: '6.0'
48
+ version: '7.2'
50
49
  - - "<"
51
50
  - !ruby/object:Gem::Version
52
- version: '8.0'
51
+ version: '9'
53
52
  - !ruby/object:Gem::Dependency
54
53
  name: encoded_id
55
54
  requirement: !ruby/object:Gem::Requirement
56
55
  requirements:
57
- - - "~>"
56
+ - - '='
58
57
  - !ruby/object:Gem::Version
59
- version: 1.0.0.rc4
58
+ version: 1.0.0.rc5
60
59
  type: :runtime
61
60
  prerelease: false
62
61
  version_requirements: !ruby/object:Gem::Requirement
63
62
  requirements:
64
- - - "~>"
63
+ - - '='
65
64
  - !ruby/object:Gem::Version
66
- version: 1.0.0.rc4
67
- - !ruby/object:Gem::Dependency
68
- name: appraisal
69
- requirement: !ruby/object:Gem::Requirement
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- version: '0'
74
- type: :development
75
- prerelease: false
76
- version_requirements: !ruby/object:Gem::Requirement
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: '0'
65
+ version: 1.0.0.rc5
81
66
  description: ActiveRecord concern to use EncodedID to turn IDs into reversible and
82
67
  human friendly obfuscated strings.
83
68
  email:
@@ -86,6 +71,9 @@ executables: []
86
71
  extensions: []
87
72
  extra_rdoc_files: []
88
73
  files:
74
+ - ".devcontainer/Dockerfile"
75
+ - ".devcontainer/compose.yml"
76
+ - ".devcontainer/devcontainer.json"
89
77
  - ".standard.yml"
90
78
  - Appraisals
91
79
  - CHANGELOG.md
@@ -95,12 +83,8 @@ files:
95
83
  - Rakefile
96
84
  - Steepfile
97
85
  - gemfiles/.bundle/config
98
- - gemfiles/rails_6.1.gemfile
99
- - gemfiles/rails_6.1.gemfile.lock
100
- - gemfiles/rails_7.0.gemfile
101
- - gemfiles/rails_7.0.gemfile.lock
102
- - gemfiles/rails_7.1.gemfile
103
- - gemfiles/rails_7.1.gemfile.lock
86
+ - gemfiles/rails_7.2.gemfile
87
+ - gemfiles/rails_8.0.gemfile
104
88
  - lib/encoded_id/rails.rb
105
89
  - lib/encoded_id/rails/annotated_id.rb
106
90
  - lib/encoded_id/rails/annotated_id_parser.rb
@@ -110,6 +94,7 @@ files:
110
94
  - lib/encoded_id/rails/finder_methods.rb
111
95
  - lib/encoded_id/rails/model.rb
112
96
  - lib/encoded_id/rails/path_param.rb
97
+ - lib/encoded_id/rails/persists.rb
113
98
  - lib/encoded_id/rails/query_methods.rb
114
99
  - lib/encoded_id/rails/salt.rb
115
100
  - lib/encoded_id/rails/slugged_id.rb
@@ -117,7 +102,9 @@ files:
117
102
  - lib/encoded_id/rails/slugged_path_param.rb
118
103
  - lib/encoded_id/rails/version.rb
119
104
  - lib/generators/encoded_id/rails/USAGE
105
+ - lib/generators/encoded_id/rails/add_columns_generator.rb
120
106
  - lib/generators/encoded_id/rails/install_generator.rb
107
+ - lib/generators/encoded_id/rails/templates/add_encoded_id_columns_migration.rb.erb
121
108
  - lib/generators/encoded_id/rails/templates/encoded_id.rb
122
109
  - rbs_collection.yaml
123
110
  - sig/encoded_id/rails.rbs
@@ -128,7 +115,6 @@ metadata:
128
115
  homepage_uri: https://github.com/stevegeek/encoded_id-rails
129
116
  source_code_uri: https://github.com/stevegeek/encoded_id-rails
130
117
  changelog_uri: https://github.com/stevegeek/encoded_id-rails/blob/master/CHANGELOG.md
131
- post_install_message:
132
118
  rdoc_options: []
133
119
  require_paths:
134
120
  - lib
@@ -136,15 +122,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
136
122
  requirements:
137
123
  - - ">="
138
124
  - !ruby/object:Gem::Version
139
- version: 2.6.0
125
+ version: 3.2.0
140
126
  required_rubygems_version: !ruby/object:Gem::Requirement
141
127
  requirements:
142
128
  - - ">="
143
129
  - !ruby/object:Gem::Version
144
130
  version: '0'
145
131
  requirements: []
146
- rubygems_version: 3.5.3
147
- signing_key:
132
+ rubygems_version: 3.6.7
148
133
  specification_version: 4
149
134
  summary: Use `encoded_id` with ActiveRecord models
150
135
  test_files: []
@@ -1,130 +0,0 @@
1
- PATH
2
- remote: ..
3
- specs:
4
- encoded_id-rails (1.0.0.beta2)
5
- activerecord (>= 6.0, < 8.0)
6
- activesupport (>= 6.0, < 8.0)
7
- encoded_id (~> 1.0.0.rc4)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- abbrev (0.1.2)
13
- activemodel (6.1.7.7)
14
- activesupport (= 6.1.7.7)
15
- activerecord (6.1.7.7)
16
- activemodel (= 6.1.7.7)
17
- activesupport (= 6.1.7.7)
18
- activesupport (6.1.7.7)
19
- concurrent-ruby (~> 1.0, >= 1.0.2)
20
- i18n (>= 1.6, < 2)
21
- minitest (>= 5.1)
22
- tzinfo (~> 2.0)
23
- zeitwerk (~> 2.3)
24
- appraisal (2.5.0)
25
- bundler
26
- rake
27
- thor (>= 0.14.0)
28
- ast (2.4.2)
29
- concurrent-ruby (1.2.3)
30
- csv (3.3.0)
31
- encoded_id (1.0.0.rc4)
32
- hashids (~> 1.0)
33
- ffi (1.16.3)
34
- fileutils (1.7.2)
35
- hashids (1.0.6)
36
- i18n (1.14.4)
37
- concurrent-ruby (~> 1.0)
38
- json (2.7.2)
39
- language_server-protocol (3.17.0.3)
40
- lint_roller (1.1.0)
41
- listen (3.9.0)
42
- rb-fsevent (~> 0.10, >= 0.10.3)
43
- rb-inotify (~> 0.9, >= 0.9.10)
44
- logger (1.6.0)
45
- minitest (5.22.3)
46
- parallel (1.24.0)
47
- parser (3.3.1.0)
48
- ast (~> 2.4.1)
49
- racc
50
- racc (1.7.3)
51
- rainbow (3.1.1)
52
- rake (13.2.1)
53
- rb-fsevent (0.11.2)
54
- rb-inotify (0.10.1)
55
- ffi (~> 1.0)
56
- rbs (3.4.4)
57
- abbrev
58
- regexp_parser (2.9.0)
59
- rexml (3.2.6)
60
- rubocop (1.62.1)
61
- json (~> 2.3)
62
- language_server-protocol (>= 3.17.0)
63
- parallel (~> 1.10)
64
- parser (>= 3.3.0.2)
65
- rainbow (>= 2.2.2, < 4.0)
66
- regexp_parser (>= 1.8, < 3.0)
67
- rexml (>= 3.2.5, < 4.0)
68
- rubocop-ast (>= 1.31.1, < 2.0)
69
- ruby-progressbar (~> 1.7)
70
- unicode-display_width (>= 2.4.0, < 3.0)
71
- rubocop-ast (1.31.3)
72
- parser (>= 3.3.1.0)
73
- rubocop-performance (1.20.2)
74
- rubocop (>= 1.48.1, < 2.0)
75
- rubocop-ast (>= 1.30.0, < 2.0)
76
- ruby-progressbar (1.13.0)
77
- securerandom (0.3.1)
78
- sqlite3 (1.7.3-arm64-darwin)
79
- standard (1.35.1)
80
- language_server-protocol (~> 3.17.0.2)
81
- lint_roller (~> 1.0)
82
- rubocop (~> 1.62.0)
83
- standard-custom (~> 1.0.0)
84
- standard-performance (~> 1.3)
85
- standard-custom (1.0.2)
86
- lint_roller (~> 1.0)
87
- rubocop (~> 1.50)
88
- standard-performance (1.3.1)
89
- lint_roller (~> 1.1)
90
- rubocop-performance (~> 1.20.2)
91
- steep (1.6.0)
92
- activesupport (>= 5.1)
93
- concurrent-ruby (>= 1.1.10)
94
- csv (>= 3.0.9)
95
- fileutils (>= 1.1.0)
96
- json (>= 2.1.0)
97
- language_server-protocol (>= 3.15, < 4.0)
98
- listen (~> 3.0)
99
- logger (>= 1.3.0)
100
- parser (>= 3.1)
101
- rainbow (>= 2.2.2, < 4.0)
102
- rbs (>= 3.1.0)
103
- securerandom (>= 0.1)
104
- strscan (>= 1.0.0)
105
- terminal-table (>= 2, < 4)
106
- strscan (3.1.0)
107
- terminal-table (3.0.2)
108
- unicode-display_width (>= 1.1.1, < 3)
109
- thor (1.3.1)
110
- tzinfo (2.0.6)
111
- concurrent-ruby (~> 1.0)
112
- unicode-display_width (2.5.0)
113
- zeitwerk (2.6.13)
114
-
115
- PLATFORMS
116
- arm64-darwin-23
117
-
118
- DEPENDENCIES
119
- activerecord (~> 6.1.7, >= 6.1.0)
120
- activesupport (~> 6.1.7, >= 6.1.0)
121
- appraisal
122
- encoded_id-rails!
123
- minitest (~> 5.0)
124
- rake (~> 13.0)
125
- sqlite3 (~> 1.5)
126
- standard (~> 1.30)
127
- steep (~> 1.5)
128
-
129
- BUNDLED WITH
130
- 2.3.26
@@ -1,16 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activesupport", "~> 7.0.4"
6
- gem "activerecord", "~> 7.0.4"
7
-
8
- group :development, :test do
9
- gem "rake", "~> 13.0"
10
- gem "minitest", "~> 5.0"
11
- gem "standard", "~> 1.30"
12
- gem "steep", "~> 1.5"
13
- gem "sqlite3", "~> 1.5"
14
- end
15
-
16
- gemspec path: "../"
@@ -1,128 +0,0 @@
1
- PATH
2
- remote: ..
3
- specs:
4
- encoded_id-rails (1.0.0.beta2)
5
- activerecord (>= 6.0, < 8.0)
6
- activesupport (>= 6.0, < 8.0)
7
- encoded_id (~> 1.0.0.rc4)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- abbrev (0.1.2)
13
- activemodel (7.0.8.1)
14
- activesupport (= 7.0.8.1)
15
- activerecord (7.0.8.1)
16
- activemodel (= 7.0.8.1)
17
- activesupport (= 7.0.8.1)
18
- activesupport (7.0.8.1)
19
- concurrent-ruby (~> 1.0, >= 1.0.2)
20
- i18n (>= 1.6, < 2)
21
- minitest (>= 5.1)
22
- tzinfo (~> 2.0)
23
- appraisal (2.5.0)
24
- bundler
25
- rake
26
- thor (>= 0.14.0)
27
- ast (2.4.2)
28
- concurrent-ruby (1.2.3)
29
- csv (3.3.0)
30
- encoded_id (1.0.0.rc4)
31
- hashids (~> 1.0)
32
- ffi (1.16.3)
33
- fileutils (1.7.2)
34
- hashids (1.0.6)
35
- i18n (1.14.4)
36
- concurrent-ruby (~> 1.0)
37
- json (2.7.2)
38
- language_server-protocol (3.17.0.3)
39
- lint_roller (1.1.0)
40
- listen (3.9.0)
41
- rb-fsevent (~> 0.10, >= 0.10.3)
42
- rb-inotify (~> 0.9, >= 0.9.10)
43
- logger (1.6.0)
44
- minitest (5.22.3)
45
- parallel (1.24.0)
46
- parser (3.3.1.0)
47
- ast (~> 2.4.1)
48
- racc
49
- racc (1.7.3)
50
- rainbow (3.1.1)
51
- rake (13.2.1)
52
- rb-fsevent (0.11.2)
53
- rb-inotify (0.10.1)
54
- ffi (~> 1.0)
55
- rbs (3.4.4)
56
- abbrev
57
- regexp_parser (2.9.0)
58
- rexml (3.2.6)
59
- rubocop (1.62.1)
60
- json (~> 2.3)
61
- language_server-protocol (>= 3.17.0)
62
- parallel (~> 1.10)
63
- parser (>= 3.3.0.2)
64
- rainbow (>= 2.2.2, < 4.0)
65
- regexp_parser (>= 1.8, < 3.0)
66
- rexml (>= 3.2.5, < 4.0)
67
- rubocop-ast (>= 1.31.1, < 2.0)
68
- ruby-progressbar (~> 1.7)
69
- unicode-display_width (>= 2.4.0, < 3.0)
70
- rubocop-ast (1.31.3)
71
- parser (>= 3.3.1.0)
72
- rubocop-performance (1.20.2)
73
- rubocop (>= 1.48.1, < 2.0)
74
- rubocop-ast (>= 1.30.0, < 2.0)
75
- ruby-progressbar (1.13.0)
76
- securerandom (0.3.1)
77
- sqlite3 (1.7.3-arm64-darwin)
78
- standard (1.35.1)
79
- language_server-protocol (~> 3.17.0.2)
80
- lint_roller (~> 1.0)
81
- rubocop (~> 1.62.0)
82
- standard-custom (~> 1.0.0)
83
- standard-performance (~> 1.3)
84
- standard-custom (1.0.2)
85
- lint_roller (~> 1.0)
86
- rubocop (~> 1.50)
87
- standard-performance (1.3.1)
88
- lint_roller (~> 1.1)
89
- rubocop-performance (~> 1.20.2)
90
- steep (1.6.0)
91
- activesupport (>= 5.1)
92
- concurrent-ruby (>= 1.1.10)
93
- csv (>= 3.0.9)
94
- fileutils (>= 1.1.0)
95
- json (>= 2.1.0)
96
- language_server-protocol (>= 3.15, < 4.0)
97
- listen (~> 3.0)
98
- logger (>= 1.3.0)
99
- parser (>= 3.1)
100
- rainbow (>= 2.2.2, < 4.0)
101
- rbs (>= 3.1.0)
102
- securerandom (>= 0.1)
103
- strscan (>= 1.0.0)
104
- terminal-table (>= 2, < 4)
105
- strscan (3.1.0)
106
- terminal-table (3.0.2)
107
- unicode-display_width (>= 1.1.1, < 3)
108
- thor (1.3.1)
109
- tzinfo (2.0.6)
110
- concurrent-ruby (~> 1.0)
111
- unicode-display_width (2.5.0)
112
-
113
- PLATFORMS
114
- arm64-darwin-23
115
-
116
- DEPENDENCIES
117
- activerecord (~> 7.0.4)
118
- activesupport (~> 7.0.4)
119
- appraisal
120
- encoded_id-rails!
121
- minitest (~> 5.0)
122
- rake (~> 13.0)
123
- sqlite3 (~> 1.5)
124
- standard (~> 1.30)
125
- steep (~> 1.5)
126
-
127
- BUNDLED WITH
128
- 2.3.26
@@ -1,140 +0,0 @@
1
- PATH
2
- remote: ..
3
- specs:
4
- encoded_id-rails (1.0.0.beta2)
5
- activerecord (>= 6.0, < 8.0)
6
- activesupport (>= 6.0, < 8.0)
7
- encoded_id (~> 1.0.0.rc4)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- abbrev (0.1.2)
13
- activemodel (7.1.3.2)
14
- activesupport (= 7.1.3.2)
15
- activerecord (7.1.3.2)
16
- activemodel (= 7.1.3.2)
17
- activesupport (= 7.1.3.2)
18
- timeout (>= 0.4.0)
19
- activesupport (7.1.3.2)
20
- base64
21
- bigdecimal
22
- concurrent-ruby (~> 1.0, >= 1.0.2)
23
- connection_pool (>= 2.2.5)
24
- drb
25
- i18n (>= 1.6, < 2)
26
- minitest (>= 5.1)
27
- mutex_m
28
- tzinfo (~> 2.0)
29
- appraisal (2.5.0)
30
- bundler
31
- rake
32
- thor (>= 0.14.0)
33
- ast (2.4.2)
34
- base64 (0.2.0)
35
- bigdecimal (3.1.7)
36
- concurrent-ruby (1.2.3)
37
- connection_pool (2.4.1)
38
- csv (3.3.0)
39
- drb (2.2.1)
40
- encoded_id (1.0.0.rc4)
41
- hashids (~> 1.0)
42
- ffi (1.16.3)
43
- fileutils (1.7.2)
44
- hashids (1.0.6)
45
- i18n (1.14.4)
46
- concurrent-ruby (~> 1.0)
47
- json (2.7.2)
48
- language_server-protocol (3.17.0.3)
49
- lint_roller (1.1.0)
50
- listen (3.9.0)
51
- rb-fsevent (~> 0.10, >= 0.10.3)
52
- rb-inotify (~> 0.9, >= 0.9.10)
53
- logger (1.6.0)
54
- minitest (5.22.3)
55
- mutex_m (0.2.0)
56
- parallel (1.24.0)
57
- parser (3.3.1.0)
58
- ast (~> 2.4.1)
59
- racc
60
- racc (1.7.3)
61
- rainbow (3.1.1)
62
- rake (13.2.1)
63
- rb-fsevent (0.11.2)
64
- rb-inotify (0.10.1)
65
- ffi (~> 1.0)
66
- rbs (3.4.4)
67
- abbrev
68
- regexp_parser (2.9.0)
69
- rexml (3.2.6)
70
- rubocop (1.62.1)
71
- json (~> 2.3)
72
- language_server-protocol (>= 3.17.0)
73
- parallel (~> 1.10)
74
- parser (>= 3.3.0.2)
75
- rainbow (>= 2.2.2, < 4.0)
76
- regexp_parser (>= 1.8, < 3.0)
77
- rexml (>= 3.2.5, < 4.0)
78
- rubocop-ast (>= 1.31.1, < 2.0)
79
- ruby-progressbar (~> 1.7)
80
- unicode-display_width (>= 2.4.0, < 3.0)
81
- rubocop-ast (1.31.3)
82
- parser (>= 3.3.1.0)
83
- rubocop-performance (1.20.2)
84
- rubocop (>= 1.48.1, < 2.0)
85
- rubocop-ast (>= 1.30.0, < 2.0)
86
- ruby-progressbar (1.13.0)
87
- securerandom (0.3.1)
88
- sqlite3 (1.7.3-arm64-darwin)
89
- standard (1.35.1)
90
- language_server-protocol (~> 3.17.0.2)
91
- lint_roller (~> 1.0)
92
- rubocop (~> 1.62.0)
93
- standard-custom (~> 1.0.0)
94
- standard-performance (~> 1.3)
95
- standard-custom (1.0.2)
96
- lint_roller (~> 1.0)
97
- rubocop (~> 1.50)
98
- standard-performance (1.3.1)
99
- lint_roller (~> 1.1)
100
- rubocop-performance (~> 1.20.2)
101
- steep (1.6.0)
102
- activesupport (>= 5.1)
103
- concurrent-ruby (>= 1.1.10)
104
- csv (>= 3.0.9)
105
- fileutils (>= 1.1.0)
106
- json (>= 2.1.0)
107
- language_server-protocol (>= 3.15, < 4.0)
108
- listen (~> 3.0)
109
- logger (>= 1.3.0)
110
- parser (>= 3.1)
111
- rainbow (>= 2.2.2, < 4.0)
112
- rbs (>= 3.1.0)
113
- securerandom (>= 0.1)
114
- strscan (>= 1.0.0)
115
- terminal-table (>= 2, < 4)
116
- strscan (3.1.0)
117
- terminal-table (3.0.2)
118
- unicode-display_width (>= 1.1.1, < 3)
119
- thor (1.3.1)
120
- timeout (0.4.1)
121
- tzinfo (2.0.6)
122
- concurrent-ruby (~> 1.0)
123
- unicode-display_width (2.5.0)
124
-
125
- PLATFORMS
126
- arm64-darwin-23
127
-
128
- DEPENDENCIES
129
- activerecord (~> 7.1)
130
- activesupport (~> 7.1)
131
- appraisal
132
- encoded_id-rails!
133
- minitest (~> 5.0)
134
- rake (~> 13.0)
135
- sqlite3 (~> 1.5)
136
- standard (~> 1.30)
137
- steep (~> 1.5)
138
-
139
- BUNDLED WITH
140
- 2.3.26