Module: Sqids::Rails::Model::ClassMethods
- Defined in:
- lib/sqids/rails/model.rb
Instance Method Summary collapse
- #generate_unique_sqid(alphabet: Sqids::Rails.alphabet, blocklist: Sqids::Rails.blocklist, min_length: Sqids::Rails.min_length) ⇒ Object
-
#has_sqid(attribute = :sqid, alphabet: Sqids::Rails.alphabet, blocklist: Sqids::Rails.blocklist, min_length: Sqids::Rails.min_length, on: Sqids::Rails.generate_sqid_on) ⇒ Object
Example using #has_sqid:.
Instance Method Details
#generate_unique_sqid(alphabet: Sqids::Rails.alphabet, blocklist: Sqids::Rails.blocklist, min_length: Sqids::Rails.min_length) ⇒ Object
95 96 97 98 99 100 101 102 103 |
# File 'lib/sqids/rails/model.rb', line 95 def generate_unique_sqid( alphabet: Sqids::Rails.alphabet, blocklist: Sqids::Rails.blocklist, min_length: Sqids::Rails.min_length ) @sqids ||= {} @sqids[[alphabet, blocklist, min_length]] ||= Sqids.new( alphabet: alphabet, blocklist: blocklist, min_length: min_length ) @sqids[[alphabet, blocklist, min_length]].encode([SecureRandom.random_number(Sqids.max_value)]) end |
#has_sqid(attribute = :sqid, alphabet: Sqids::Rails.alphabet, blocklist: Sqids::Rails.blocklist, min_length: Sqids::Rails.min_length, on: Sqids::Rails.generate_sqid_on) ⇒ Object
Example using #has_sqid:
# Schema: User(sqid:string, long_sqid:string)
class User < ApplicationRecord
include Sqids::Rails::Model
has_sqid
has_sqid :long_sqid, min_length: 24
end
user = User.new
user.save
user.sqid # => "lzNKgEb6ZuaU"
user.sqid_long # => "4y3SVm9M2aV8Olu6p4zZoGij"
user.regenerate_sqid
user.regenerate_long_sqid
SecureRandom.random_number(Sqids.max_value) is used to generate the random number to encode.
Note that it’s still possible to generate a race condition in the database in the same way that validates_uniqueness_of can. You’re encouraged to add a unique index in the database to deal with this even more unlikely scenario.
See the Sqids Ruby documentation for more information on the options.
Options
- :alphabet
-
The alphabet to use for encoding. Default is
Sqids::Rails.alphabet
. The minimum alphabet length is 3 characters. The alphabet cannot contain any multibyte characters. - :blocklist
-
The blocklist to use for encoding. Default is
Sqids::Rails.blocklist
. - :min_length
-
The minimum length of the generated sqid, from 0-255. Default is
Sqids::Rails.min_length
. Sqids cannot generate IDs up to a certain length, only at least a certain length. - :on
-
The callback when the value is generated. When called with
on: :initialize
, the value is generated in anafter_initialize
callback, otherwise the value will be used in abefore_
callback. When not specified,:on
will use the value ofSqids::Rails.generate_sqid_on
, which defaults to:initialize
.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/sqids/rails/model.rb', line 55 def has_sqid( attribute = :sqid, alphabet: Sqids::Rails.alphabet, blocklist: Sqids::Rails.blocklist, min_length: Sqids::Rails.min_length, on: Sqids::Rails.generate_sqid_on ) if alphabet.length < 3 raise AlphabetError, "Sqid requires an alphabet of at least 3 characters" end if alphabet.each_char.any? { |char| char.bytesize > 1 } raise AlphabetError, "Sqid alphabet cannot contain multibyte characters" end if alphabet.chars.uniq.length != alphabet.length raise AlphabetError, "Sqid alphabet must contain unique characters" end if min_length < 0 || min_length > 255 raise MinimumLengthError, "Sqid requires a minimum length between 0 and 255 characters" end define_method(:"regenerate_#{attribute}") do update!( attribute => self.class.generate_unique_sqid( alphabet: alphabet, blocklist: blocklist, min_length: min_length ) ) end set_callback(on, (on == :initialize) ? :after : :before) do if new_record? && !query_attribute(attribute) send( :"#{attribute}=", self.class.generate_unique_sqid(alphabet: alphabet, blocklist: blocklist, min_length: min_length) ) end end end |