encoded_id-rails 1.0.0.rc6 → 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/CHANGELOG.md +29 -4
- data/README.md +44 -33
- data/context/encoded_id-rails.md +298 -80
- data/context/encoded_id.md +229 -75
- data/lib/encoded_id/rails/active_record_finders.rb +16 -3
- data/lib/encoded_id/rails/annotated_id.rb +11 -14
- data/lib/encoded_id/rails/annotated_id_parser.rb +1 -0
- data/lib/encoded_id/rails/coder.rb +45 -18
- data/lib/encoded_id/rails/composite_id_base.rb +39 -0
- data/lib/encoded_id/rails/configuration.rb +28 -12
- data/lib/encoded_id/rails/encoder_methods.rb +24 -9
- data/lib/encoded_id/rails/finder_methods.rb +1 -0
- data/lib/encoded_id/rails/model.rb +35 -5
- data/lib/encoded_id/rails/path_param.rb +1 -0
- data/lib/encoded_id/rails/persists.rb +7 -5
- data/lib/encoded_id/rails/query_methods.rb +1 -0
- data/lib/encoded_id/rails/salt.rb +1 -0
- data/lib/encoded_id/rails/slugged_id.rb +11 -14
- data/lib/encoded_id/rails/slugged_id_parser.rb +1 -0
- data/lib/encoded_id/rails/slugged_path_param.rb +1 -0
- data/lib/encoded_id/rails.rb +2 -0
- data/lib/generators/encoded_id/rails/install_generator.rb +36 -2
- data/lib/generators/encoded_id/rails/templates/hashids_encoded_id.rb +122 -0
- data/lib/generators/encoded_id/rails/templates/{encoded_id.rb → sqids_encoded_id.rb} +29 -11
- metadata +7 -5
|
@@ -6,7 +6,10 @@ module EncodedId
|
|
|
6
6
|
module Rails
|
|
7
7
|
# Configuration class for initializer
|
|
8
8
|
class Configuration
|
|
9
|
-
|
|
9
|
+
VALID_ENCODERS = [:hashids, :sqids].freeze
|
|
10
|
+
DEFAULT_ENCODER = :sqids
|
|
11
|
+
|
|
12
|
+
# @rbs @salt: String?
|
|
10
13
|
# @rbs @character_group_size: Integer
|
|
11
14
|
# @rbs @alphabet: ::EncodedId::Alphabet
|
|
12
15
|
# @rbs @id_length: Integer
|
|
@@ -14,12 +17,15 @@ module EncodedId
|
|
|
14
17
|
# @rbs @annotation_method_name: Symbol
|
|
15
18
|
# @rbs @model_to_param_returns_encoded_id: bool
|
|
16
19
|
# @rbs @blocklist: ::EncodedId::Blocklist
|
|
20
|
+
# @rbs @blocklist_mode: Symbol
|
|
21
|
+
# @rbs @blocklist_max_length: Integer
|
|
17
22
|
# @rbs @group_separator: String
|
|
18
23
|
# @rbs @slugged_id_separator: String
|
|
19
24
|
# @rbs @annotated_id_separator: String
|
|
20
25
|
# @rbs @encoder: Symbol
|
|
26
|
+
# @rbs @downcase_on_decode: bool
|
|
21
27
|
|
|
22
|
-
attr_accessor :salt #: String
|
|
28
|
+
attr_accessor :salt #: String?
|
|
23
29
|
attr_accessor :character_group_size #: Integer
|
|
24
30
|
attr_accessor :alphabet #: ::EncodedId::Alphabet
|
|
25
31
|
attr_accessor :id_length #: Integer
|
|
@@ -27,6 +33,9 @@ module EncodedId
|
|
|
27
33
|
attr_accessor :annotation_method_name #: Symbol
|
|
28
34
|
attr_accessor :model_to_param_returns_encoded_id #: bool
|
|
29
35
|
attr_accessor :blocklist #: ::EncodedId::Blocklist
|
|
36
|
+
attr_accessor :blocklist_mode #: Symbol
|
|
37
|
+
attr_accessor :blocklist_max_length #: Integer
|
|
38
|
+
attr_accessor :downcase_on_decode #: bool
|
|
30
39
|
attr_reader :group_separator #: String
|
|
31
40
|
attr_reader :slugged_id_separator #: String
|
|
32
41
|
attr_reader :annotated_id_separator #: String
|
|
@@ -43,14 +52,18 @@ module EncodedId
|
|
|
43
52
|
@annotation_method_name = :annotation_for_encoded_id
|
|
44
53
|
@annotated_id_separator = "_"
|
|
45
54
|
@model_to_param_returns_encoded_id = false
|
|
46
|
-
@encoder =
|
|
55
|
+
@encoder = DEFAULT_ENCODER
|
|
47
56
|
@blocklist = ::EncodedId::Blocklist.empty
|
|
57
|
+
@blocklist_mode = :length_threshold
|
|
58
|
+
@blocklist_max_length = 32
|
|
59
|
+
@downcase_on_decode = false
|
|
60
|
+
@salt = nil
|
|
48
61
|
end
|
|
49
62
|
|
|
50
63
|
# @rbs (Symbol value) -> Symbol
|
|
51
64
|
def encoder=(value)
|
|
52
|
-
unless
|
|
53
|
-
raise ArgumentError, "Encoder must be one of: #{
|
|
65
|
+
unless VALID_ENCODERS.include?(value)
|
|
66
|
+
raise ArgumentError, "Encoder must be one of: #{VALID_ENCODERS.join(", ")}"
|
|
54
67
|
end
|
|
55
68
|
@encoder = value
|
|
56
69
|
end
|
|
@@ -67,25 +80,28 @@ module EncodedId
|
|
|
67
80
|
|
|
68
81
|
# @rbs (String value) -> String
|
|
69
82
|
def slugged_id_separator=(value)
|
|
70
|
-
|
|
71
|
-
raise ArgumentError, "Slugged ID separator characters must not be part of the alphabet or the same as the group separator"
|
|
72
|
-
end
|
|
83
|
+
validate_id_separator!(value, "Slugged ID")
|
|
73
84
|
@slugged_id_separator = value
|
|
74
85
|
end
|
|
75
86
|
|
|
76
87
|
# @rbs (String value) -> String
|
|
77
88
|
def annotated_id_separator=(value)
|
|
78
|
-
|
|
79
|
-
raise ArgumentError, "Annotated ID separator characters must not be part of the alphabet or the same as the group separator"
|
|
80
|
-
end
|
|
89
|
+
validate_id_separator!(value, "Annotated ID")
|
|
81
90
|
@annotated_id_separator = value
|
|
82
91
|
end
|
|
83
92
|
|
|
84
93
|
private
|
|
85
94
|
|
|
95
|
+
# @rbs (String value, String separator_name) -> void
|
|
96
|
+
def validate_id_separator!(value, separator_name)
|
|
97
|
+
if value.blank? || value == group_separator || !valid_separator?(value, alphabet)
|
|
98
|
+
raise ArgumentError, "#{separator_name} separator characters must not be part of the alphabet or the same as the group separator"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
86
102
|
# @rbs (String separator, ::EncodedId::Alphabet characters) -> bool
|
|
87
103
|
def valid_separator?(separator, characters)
|
|
88
|
-
separator.chars.none? {
|
|
104
|
+
separator.chars.none? { characters.include?(_1) }
|
|
89
105
|
end
|
|
90
106
|
end
|
|
91
107
|
end
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
module EncodedId
|
|
6
6
|
module Rails
|
|
7
|
+
# Provides methods for encoding and decoding IDs, extended into ActiveRecord models.
|
|
7
8
|
module EncoderMethods
|
|
9
|
+
# @rbs!
|
|
10
|
+
# interface _EncodedIdModel
|
|
11
|
+
# def encoded_id_options: () -> Hash[Symbol, untyped]
|
|
12
|
+
# end
|
|
8
13
|
# @rbs (Array[Integer] | Integer ids, ?Hash[Symbol, untyped] options) -> String
|
|
9
14
|
def encode_encoded_id(ids, options = {})
|
|
10
15
|
raise StandardError, "You must pass an ID or array of IDs" if ids.blank?
|
|
@@ -15,8 +20,9 @@ module EncodedId
|
|
|
15
20
|
def decode_encoded_id(slugged_encoded_id, options = {})
|
|
16
21
|
return if slugged_encoded_id.blank?
|
|
17
22
|
raise StandardError, "You must pass a string encoded ID" unless slugged_encoded_id.is_a?(String)
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
config = EncodedId::Rails.configuration
|
|
24
|
+
annotated_encoded_id = SluggedIdParser.new(slugged_encoded_id, separator: config.slugged_id_separator).id
|
|
25
|
+
encoded_id = AnnotatedIdParser.new(annotated_encoded_id, separator: config.annotated_id_separator).id
|
|
20
26
|
return if !encoded_id || encoded_id.blank?
|
|
21
27
|
encoded_id_coder(options).decode(encoded_id)
|
|
22
28
|
end
|
|
@@ -29,16 +35,25 @@ module EncodedId
|
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
# @rbs (?Hash[Symbol, untyped] options) -> EncodedId::Rails::Coder
|
|
38
|
+
# | (_EncodedIdModel self, ?Hash[Symbol, untyped] options) -> EncodedId::Rails::Coder
|
|
32
39
|
def encoded_id_coder(options = {})
|
|
33
40
|
config = EncodedId::Rails.configuration
|
|
41
|
+
# Merge model-level options with call-time options (call-time options take precedence)
|
|
42
|
+
# @type var model_options: Hash[Symbol, untyped]
|
|
43
|
+
model_options = respond_to?(:encoded_id_options) ? encoded_id_options : {} #: Hash[Symbol, untyped]
|
|
44
|
+
merged_options = model_options.merge(options)
|
|
45
|
+
|
|
34
46
|
EncodedId::Rails::Coder.new(
|
|
35
|
-
salt:
|
|
36
|
-
id_length:
|
|
37
|
-
character_group_size:
|
|
38
|
-
alphabet:
|
|
39
|
-
separator:
|
|
40
|
-
encoder:
|
|
41
|
-
blocklist:
|
|
47
|
+
salt: merged_options[:salt] || encoded_id_salt,
|
|
48
|
+
id_length: merged_options[:id_length] || config.id_length,
|
|
49
|
+
character_group_size: merged_options.key?(:character_group_size) ? merged_options[:character_group_size] : config.character_group_size,
|
|
50
|
+
alphabet: merged_options[:alphabet] || config.alphabet,
|
|
51
|
+
separator: merged_options.key?(:separator) ? merged_options[:separator] : config.group_separator,
|
|
52
|
+
encoder: merged_options[:encoder] || config.encoder,
|
|
53
|
+
blocklist: merged_options[:blocklist] || config.blocklist,
|
|
54
|
+
blocklist_mode: merged_options[:blocklist_mode] || config.blocklist_mode,
|
|
55
|
+
blocklist_max_length: merged_options[:blocklist_max_length] || config.blocklist_max_length,
|
|
56
|
+
downcase_on_decode: merged_options.key?(:downcase_on_decode) ? merged_options[:downcase_on_decode] : config.downcase_on_decode
|
|
42
57
|
)
|
|
43
58
|
end
|
|
44
59
|
end
|
|
@@ -7,6 +7,7 @@ require "encoded_id"
|
|
|
7
7
|
|
|
8
8
|
module EncodedId
|
|
9
9
|
module Rails
|
|
10
|
+
# Main module for adding encoded ID functionality to ActiveRecord models.
|
|
10
11
|
module Model
|
|
11
12
|
# @rbs!
|
|
12
13
|
# extend ::EncodedId::Rails::EncoderMethods
|
|
@@ -27,13 +28,40 @@ module EncodedId
|
|
|
27
28
|
base.extend(EncoderMethods)
|
|
28
29
|
base.extend(FinderMethods)
|
|
29
30
|
base.extend(QueryMethods)
|
|
31
|
+
base.extend(ClassMethods)
|
|
30
32
|
|
|
31
|
-
#
|
|
33
|
+
# Conditionally include PathParam based on global configuration
|
|
32
34
|
if EncodedId::Rails.configuration.model_to_param_returns_encoded_id
|
|
33
35
|
base.include(EncodedId::Rails::PathParam)
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
|
39
|
+
module ClassMethods
|
|
40
|
+
# Configure encoder options for this specific model
|
|
41
|
+
# @example
|
|
42
|
+
# class MyModel < ApplicationRecord
|
|
43
|
+
# include EncodedId::Rails::Model
|
|
44
|
+
# encoded_id_config encoder: :hashids
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# @rbs (**untyped options) -> void
|
|
48
|
+
def encoded_id_config(**options)
|
|
49
|
+
@encoded_id_options = options
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Walks up the inheritance chain to find options if not set on this class
|
|
53
|
+
# @rbs () -> Hash[Symbol, untyped]
|
|
54
|
+
def encoded_id_options
|
|
55
|
+
return @encoded_id_options if defined?(@encoded_id_options) && @encoded_id_options
|
|
56
|
+
|
|
57
|
+
if superclass.respond_to?(:encoded_id_options)
|
|
58
|
+
superclass.encoded_id_options
|
|
59
|
+
else
|
|
60
|
+
{}
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
37
65
|
attr_accessor :encoded_id_memoized_with_id #: untyped
|
|
38
66
|
|
|
39
67
|
# @rbs () -> void
|
|
@@ -66,10 +94,11 @@ module EncodedId
|
|
|
66
94
|
return @encoded_id if defined?(@encoded_id)
|
|
67
95
|
|
|
68
96
|
encoded = encoded_id_hash
|
|
69
|
-
|
|
97
|
+
config = EncodedId::Rails.configuration
|
|
98
|
+
annotated_by = config.annotation_method_name
|
|
70
99
|
return @encoded_id = encoded unless annotated_by && encoded
|
|
71
100
|
|
|
72
|
-
separator =
|
|
101
|
+
separator = config.annotated_id_separator
|
|
73
102
|
self.encoded_id_memoized_with_id = id
|
|
74
103
|
@encoded_id = EncodedId::Rails::AnnotatedId.new(id_part: encoded, annotation: send(annotated_by.to_s), separator: separator).annotated_id
|
|
75
104
|
end
|
|
@@ -80,8 +109,9 @@ module EncodedId
|
|
|
80
109
|
check_and_clear_memoization
|
|
81
110
|
return @slugged_encoded_id if defined?(@slugged_encoded_id)
|
|
82
111
|
|
|
83
|
-
|
|
84
|
-
|
|
112
|
+
config = EncodedId::Rails.configuration
|
|
113
|
+
with = config.slug_value_method_name
|
|
114
|
+
separator = config.slugged_id_separator
|
|
85
115
|
encoded = encoded_id
|
|
86
116
|
return unless encoded
|
|
87
117
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
module EncodedId
|
|
6
6
|
module Rails
|
|
7
|
+
# Provides persistence of encoded IDs to database columns with validation and callbacks.
|
|
7
8
|
module Persists
|
|
8
9
|
# @rbs (untyped base) -> void
|
|
9
10
|
def self.included(base)
|
|
@@ -33,7 +34,6 @@ module EncodedId
|
|
|
33
34
|
end
|
|
34
35
|
end
|
|
35
36
|
|
|
36
|
-
# Method provided by model
|
|
37
37
|
# @rbs!
|
|
38
38
|
# include ::ActiveRecord::Persistence
|
|
39
39
|
#
|
|
@@ -52,7 +52,7 @@ module EncodedId
|
|
|
52
52
|
# def clear_normalized_encoded_id_change: () -> void
|
|
53
53
|
|
|
54
54
|
# On duplication we need to reset the encoded ID to nil as this new record will have a new ID.
|
|
55
|
-
# We
|
|
55
|
+
# We also prevent these changes from marking the record as dirty.
|
|
56
56
|
# @rbs () -> untyped
|
|
57
57
|
def dup
|
|
58
58
|
copy = super
|
|
@@ -85,15 +85,17 @@ module EncodedId
|
|
|
85
85
|
def check_encoded_id_persisted!
|
|
86
86
|
validate_id_for_encoded_id!
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
klass = self.class
|
|
89
|
+
klass_name = klass.name
|
|
90
|
+
encoded_from_current_id = klass.encode_normalized_encoded_id(resolved_id)
|
|
89
91
|
|
|
90
92
|
if normalized_encoded_id != encoded_from_current_id
|
|
91
|
-
raise StandardError, "The persisted encoded ID #{normalized_encoded_id} for #{
|
|
93
|
+
raise StandardError, "The persisted encoded ID #{normalized_encoded_id} for #{klass_name} is not the same as currently computing #{encoded_from_current_id}"
|
|
92
94
|
end
|
|
93
95
|
|
|
94
96
|
return if prefixed_encoded_id == encoded_id
|
|
95
97
|
|
|
96
|
-
raise StandardError, "The persisted prefixed encoded ID (for #{
|
|
98
|
+
raise StandardError, "The persisted prefixed encoded ID (for #{klass_name} with id: #{id}, normalized_encoded_id: #{normalized_encoded_id}) is not correct: it is #{prefixed_encoded_id} instead of #{encoded_id}"
|
|
97
99
|
end
|
|
98
100
|
|
|
99
101
|
# @rbs () -> bool
|
|
@@ -2,28 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
# rbs_inline: enabled
|
|
4
4
|
|
|
5
|
-
require "cgi"
|
|
6
|
-
|
|
7
5
|
module EncodedId
|
|
8
6
|
module Rails
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# @rbs @id_part: String
|
|
12
|
-
# @rbs @separator: String
|
|
13
|
-
|
|
7
|
+
# Represents an encoded ID with a slug prefix (e.g., "my-post--ABC123").
|
|
8
|
+
class SluggedId < CompositeIdBase
|
|
14
9
|
# @rbs (slug_part: String, id_part: String, ?separator: String) -> void
|
|
15
10
|
def initialize(slug_part:, id_part:, separator: "--")
|
|
16
|
-
|
|
17
|
-
@id_part = id_part
|
|
18
|
-
@separator = separator
|
|
11
|
+
super(first_part: slug_part, id_part: id_part, separator: separator)
|
|
19
12
|
end
|
|
20
13
|
|
|
21
14
|
# @rbs return: String
|
|
22
15
|
def slugged_id
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
build_composite_id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
# @rbs return: String
|
|
22
|
+
def invalid_id_error_message
|
|
23
|
+
"The model does not return a valid ID and/or slug"
|
|
27
24
|
end
|
|
28
25
|
end
|
|
29
26
|
end
|
data/lib/encoded_id/rails.rb
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
require_relative "rails/configuration"
|
|
6
6
|
require_relative "rails/coder"
|
|
7
|
+
require_relative "rails/composite_id_base"
|
|
7
8
|
require_relative "rails/slugged_id"
|
|
8
9
|
require_relative "rails/slugged_id_parser"
|
|
9
10
|
require_relative "rails/annotated_id"
|
|
@@ -20,6 +21,7 @@ require_relative "rails/active_record_finders"
|
|
|
20
21
|
require_relative "rails/railtie"
|
|
21
22
|
|
|
22
23
|
module EncodedId
|
|
24
|
+
# Rails integration for EncodedId, providing configuration and ActiveRecord extensions.
|
|
23
25
|
module Rails
|
|
24
26
|
# Configuration
|
|
25
27
|
# @rbs self.@configuration: EncodedId::Rails::Configuration?
|
|
@@ -9,9 +9,43 @@ module EncodedId
|
|
|
9
9
|
class InstallGenerator < ::Rails::Generators::Base
|
|
10
10
|
source_root File.expand_path(__dir__)
|
|
11
11
|
|
|
12
|
-
desc "Creates an initializer for the gem."
|
|
12
|
+
desc "Creates an encoder-specific initializer for the gem."
|
|
13
|
+
|
|
14
|
+
class_option :encoder,
|
|
15
|
+
type: :string,
|
|
16
|
+
aliases: "-e",
|
|
17
|
+
desc: "Encoder to use (sqids or hashids)",
|
|
18
|
+
default: nil
|
|
19
|
+
|
|
20
|
+
def ask_for_encoder
|
|
21
|
+
@encoder = options[:encoder]
|
|
22
|
+
|
|
23
|
+
@encoder ||= ask("Which encoder would you like to use?",
|
|
24
|
+
limited_to: %w[sqids hashids],
|
|
25
|
+
default: "sqids")
|
|
26
|
+
|
|
27
|
+
unless %w[sqids hashids].include?(@encoder)
|
|
28
|
+
say "Invalid encoder '#{@encoder}'. Must be 'sqids' or 'hashids'.", :red
|
|
29
|
+
exit 1
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
13
33
|
def copy_tasks
|
|
14
|
-
|
|
34
|
+
template_name = (@encoder == "sqids") ? "sqids_encoded_id.rb" : "hashids_encoded_id.rb"
|
|
35
|
+
template "templates/#{template_name}", "config/initializers/encoded_id.rb"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def show_readme
|
|
39
|
+
say "\n" + ("=" * 70), :green
|
|
40
|
+
if @encoder == "sqids"
|
|
41
|
+
say "Sqids encoder installed!", :green
|
|
42
|
+
say "This encoder does not require a salt and generates URL-safe IDs.", :green
|
|
43
|
+
else
|
|
44
|
+
say "Hashids encoder installed!", :green
|
|
45
|
+
say "⚠️ IMPORTANT: You MUST configure a salt in config/initializers/encoded_id.rb", :yellow
|
|
46
|
+
say "Uncomment and set the 'config.salt' line before using Hashids.", :yellow
|
|
47
|
+
end
|
|
48
|
+
say ("=" * 70) + "\n", :green
|
|
15
49
|
end
|
|
16
50
|
end
|
|
17
51
|
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
EncodedId::Rails.configure do |config|
|
|
4
|
+
# The encoder to use for generating encoded IDs.
|
|
5
|
+
#
|
|
6
|
+
# Hashids generates short, unique, non-sequential IDs from numbers using a salt. The salt ensures that
|
|
7
|
+
# the same ID produces different encoded values. Learn more: https://hashids.org
|
|
8
|
+
#
|
|
9
|
+
config.encoder = :hashids
|
|
10
|
+
|
|
11
|
+
# The salt is used in the Hashids algorithm to generate the encoded ID. It ensures that the same ID will result in
|
|
12
|
+
# a different encoded ID. You must configure one and it must be longer that 4 characters. It can be configured on a
|
|
13
|
+
# model by model basis too.
|
|
14
|
+
#
|
|
15
|
+
config.salt = "<%= SecureRandom.hex(24) %>"
|
|
16
|
+
|
|
17
|
+
# The number of characters of the encoded ID that are grouped before the hyphen separator is inserted.
|
|
18
|
+
# `nil` disables grouping.
|
|
19
|
+
#
|
|
20
|
+
# nil -> abcdefghijklmnop
|
|
21
|
+
# 4 -> abcd-efgh-ijkl-mnop
|
|
22
|
+
# 8 -> abcdefgh-ijklmnop
|
|
23
|
+
#
|
|
24
|
+
# Default: 4
|
|
25
|
+
#
|
|
26
|
+
# config.character_group_size = 4
|
|
27
|
+
|
|
28
|
+
# The separator used between character groups in the encoded ID.
|
|
29
|
+
# `nil` disables grouping.
|
|
30
|
+
#
|
|
31
|
+
# Default: "-"
|
|
32
|
+
#
|
|
33
|
+
# config.group_separator = "-"
|
|
34
|
+
|
|
35
|
+
# The characters allowed in the encoded ID.
|
|
36
|
+
# Note, Hashids requires at least 16 unique alphabet characters.
|
|
37
|
+
#
|
|
38
|
+
# Default: a reduced character set Crockford alphabet and split groups, see https://www.crockford.com/wrmg/base32.html
|
|
39
|
+
#
|
|
40
|
+
# config.alphabet = ::EncodedId::Alphabet.new("0123456789abcdef")
|
|
41
|
+
|
|
42
|
+
# The minimum length of the encoded ID. Note that this is not a hard limit, the actual length may be longer as Hashids
|
|
43
|
+
# may expand the length as needed to encode the full input. However encoded IDs will never be shorter than this.
|
|
44
|
+
#
|
|
45
|
+
# 4 -> "abcd"
|
|
46
|
+
# 8 -> "abcd-efgh" (with character_group_size = 4)
|
|
47
|
+
#
|
|
48
|
+
# Default: 8
|
|
49
|
+
#
|
|
50
|
+
# config.id_length = 8
|
|
51
|
+
|
|
52
|
+
# The name of the method that returns the value to be used in the slug.
|
|
53
|
+
#
|
|
54
|
+
# Default: :name_for_encoded_id_slug
|
|
55
|
+
#
|
|
56
|
+
# config.slug_value_method_name = :name_for_encoded_id_slug
|
|
57
|
+
|
|
58
|
+
# The separator used between the slug and the encoded ID.
|
|
59
|
+
# `nil` disables grouping.
|
|
60
|
+
#
|
|
61
|
+
# Default: "--"
|
|
62
|
+
#
|
|
63
|
+
# config.slugged_id_separator = "--"
|
|
64
|
+
|
|
65
|
+
# The name of the method that returns the annotation to be used in the annotated ID.
|
|
66
|
+
#
|
|
67
|
+
# Default: :annotation_for_encoded_id
|
|
68
|
+
#
|
|
69
|
+
# config.annotation_method_name = :annotation_for_encoded_id
|
|
70
|
+
|
|
71
|
+
# The separator used between the annotation and the encoded ID.
|
|
72
|
+
# `nil` disables annotation.
|
|
73
|
+
#
|
|
74
|
+
# Default: "_"
|
|
75
|
+
#
|
|
76
|
+
# config.annotated_id_separator = "_"
|
|
77
|
+
|
|
78
|
+
# When true, models that include EncodedId::Rails::Model will automatically have their to_param method
|
|
79
|
+
# return the encoded ID (equivalent to also including EncodedId::Rails::PathParam).
|
|
80
|
+
# This makes any model with EncodedId::Rails::Model automatically use encoded IDs in URLs.
|
|
81
|
+
#
|
|
82
|
+
# Default: false
|
|
83
|
+
#
|
|
84
|
+
# config.model_to_param_returns_encoded_id = true
|
|
85
|
+
|
|
86
|
+
# When true, the encoded ID will be downcased before decoding. This can be used for
|
|
87
|
+
# case-insensitive matching on a compatible alphabet, but note that encoded IDs are case-sensitive by default.
|
|
88
|
+
# For backwards compatibility with pre-v1 versions, set this to true.
|
|
89
|
+
#
|
|
90
|
+
# Default: false
|
|
91
|
+
#
|
|
92
|
+
# config.downcase_on_decode = false
|
|
93
|
+
|
|
94
|
+
# A list of words that should not appear in generated encoded IDs.
|
|
95
|
+
# For the Hashids encoder, IDs containing blocklisted words will raise an error when generated.
|
|
96
|
+
# Should be an instance of EncodedId::Blocklist, or an Array or Set of strings.
|
|
97
|
+
#
|
|
98
|
+
# Default: EncodedId::Blocklist.empty
|
|
99
|
+
# Available built-in blocklists:
|
|
100
|
+
# - EncodedId::Blocklist.empty - no blocked words
|
|
101
|
+
# - EncodedId::Blocklist.minimal - common English profanity
|
|
102
|
+
#
|
|
103
|
+
# config.blocklist = EncodedId::Blocklist.minimal
|
|
104
|
+
|
|
105
|
+
# Controls when blocklist checking occurs. This can improve performance for apps generating many IDs.
|
|
106
|
+
#
|
|
107
|
+
# Options:
|
|
108
|
+
# - :length_threshold (default) - Only check IDs up to blocklist_max_length characters
|
|
109
|
+
# - :always - Check all IDs regardless of length
|
|
110
|
+
# - :raise_if_likely - Raise error if configuration likely causes performance issues
|
|
111
|
+
#
|
|
112
|
+
# Default: :length_threshold
|
|
113
|
+
#
|
|
114
|
+
# config.blocklist_mode = :length_threshold
|
|
115
|
+
|
|
116
|
+
# Maximum length threshold for blocklist checking when using :length_threshold mode.
|
|
117
|
+
# IDs longer than this will skip blocklist checking for better performance.
|
|
118
|
+
#
|
|
119
|
+
# Default: 32
|
|
120
|
+
#
|
|
121
|
+
# config.blocklist_max_length = 32
|
|
122
|
+
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
EncodedId::Rails.configure do |config|
|
|
4
|
-
# The
|
|
5
|
-
# a different encoded ID. You must configure one and it must be longer that 4 characters. It can be configured on a
|
|
6
|
-
# model by model basis too.
|
|
4
|
+
# The encoder to use for generating encoded IDs.
|
|
7
5
|
#
|
|
8
|
-
#
|
|
6
|
+
# Sqids generates short, unique, URL-safe IDs from numbers. Learn more: https://sqids.org
|
|
7
|
+
#
|
|
8
|
+
config.encoder = :sqids
|
|
9
9
|
|
|
10
10
|
# The number of characters of the encoded ID that are grouped before the hyphen separator is inserted.
|
|
11
11
|
# `nil` disables grouping.
|
|
@@ -26,13 +26,13 @@ EncodedId::Rails.configure do |config|
|
|
|
26
26
|
# config.group_separator = "-"
|
|
27
27
|
|
|
28
28
|
# The characters allowed in the encoded ID.
|
|
29
|
-
# Note,
|
|
29
|
+
# Note, Sqids requires at least 5 unique alphabet characters.
|
|
30
30
|
#
|
|
31
31
|
# Default: a reduced character set Crockford alphabet and split groups, see https://www.crockford.com/wrmg/base32.html
|
|
32
32
|
#
|
|
33
33
|
# config.alphabet = ::EncodedId::Alphabet.new("0123456789abcdef")
|
|
34
34
|
|
|
35
|
-
# The minimum length of the encoded ID. Note that this is not a hard limit, the actual length may be longer as
|
|
35
|
+
# The minimum length of the encoded ID. Note that this is not a hard limit, the actual length may be longer as Sqids
|
|
36
36
|
# may expand the length as needed to encode the full input. However encoded IDs will never be shorter than this.
|
|
37
37
|
#
|
|
38
38
|
# 4 -> "abcd"
|
|
@@ -76,15 +76,15 @@ EncodedId::Rails.configure do |config|
|
|
|
76
76
|
#
|
|
77
77
|
# config.model_to_param_returns_encoded_id = true
|
|
78
78
|
|
|
79
|
-
#
|
|
80
|
-
#
|
|
79
|
+
# When true, the encoded ID will be downcased before decoding. This can be used for
|
|
80
|
+
# case-insensitive matching on a compatible alphabet, but note that encoded IDs are case-sensitive by default.
|
|
81
|
+
# For backwards compatibility with pre-v1 versions, set this to true.
|
|
81
82
|
#
|
|
82
|
-
# Default:
|
|
83
|
+
# Default: false
|
|
83
84
|
#
|
|
84
|
-
# config.
|
|
85
|
+
# config.downcase_on_decode = false
|
|
85
86
|
|
|
86
87
|
# A list of words that should not appear in generated encoded IDs.
|
|
87
|
-
# For the HashIds encoder, IDs containing blocklisted words will raise an error when generated.
|
|
88
88
|
# For the Sqids encoder, the algorithm will automatically avoid generating IDs containing these words.
|
|
89
89
|
# Should be an instance of EncodedId::Blocklist, or an Array or Set of strings.
|
|
90
90
|
#
|
|
@@ -95,4 +95,22 @@ EncodedId::Rails.configure do |config|
|
|
|
95
95
|
# - EncodedId::Blocklist.sqids_blocklist - the default blocklist from the Sqids gem
|
|
96
96
|
#
|
|
97
97
|
# config.blocklist = EncodedId::Blocklist.minimal
|
|
98
|
+
|
|
99
|
+
# Controls when blocklist checking occurs. This can improve performance for apps generating many IDs.
|
|
100
|
+
#
|
|
101
|
+
# Options:
|
|
102
|
+
# - :length_threshold (default) - Only check IDs up to blocklist_max_length characters
|
|
103
|
+
# - :always - Check all IDs regardless of length
|
|
104
|
+
# - :raise_if_likely - Raise error if configuration likely causes performance issues
|
|
105
|
+
#
|
|
106
|
+
# Default: :length_threshold
|
|
107
|
+
#
|
|
108
|
+
# config.blocklist_mode = :length_threshold
|
|
109
|
+
|
|
110
|
+
# Maximum length threshold for blocklist checking when using :length_threshold mode.
|
|
111
|
+
# IDs longer than this will skip blocklist checking for better performance.
|
|
112
|
+
#
|
|
113
|
+
# Default: 32
|
|
114
|
+
#
|
|
115
|
+
# config.blocklist_max_length = 32
|
|
98
116
|
end
|