Module: RailsStuff::RandomUniqAttr
- Defined in:
- lib/rails_stuff/random_uniq_attr.rb
Overview
Provides save way to generate uniq random values for ActiveRecord models. You need to make field nullable and add unique index on it. The way it works:
-
Instance is saved as usual
-
If random fields are not empty, it does nothing
-
Generates random value and tries to update instance
-
If ‘RecordNotUnique` is occured, it keeps trying to generate new values.
Constant Summary collapse
- DEFAULT_GENERATOR =
->(*) { SecureRandom.hex(32) }
- MAX_ATTEMPTS =
10
Class Method Summary collapse
-
.friendly_token(length = 32) ⇒ Object
Made from ‘Devise.firendly_token` with increased length.
Instance Method Summary collapse
-
#random_uniq_attr(field, **options, &block) ⇒ Object
Generates necessary methods and setups on-create callback for the ‘field`.
Class Method Details
.friendly_token(length = 32) ⇒ Object
Made from ‘Devise.firendly_token` with increased length.
17 18 19 |
# File 'lib/rails_stuff/random_uniq_attr.rb', line 17 def friendly_token(length = 32) SecureRandom.urlsafe_base64(length).tr('lIO0', 'sxyz') end |
Instance Method Details
#random_uniq_attr(field, **options, &block) ⇒ Object
Generates necessary methods and setups on-create callback for the ‘field`. You can optionally pass custom generator function:
random_uniq_attr(:code) { |instance| my_random(instance) }
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/rails_stuff/random_uniq_attr.rb', line 27 def random_uniq_attr(field, **, &block) set_method = :"set_#{field}" generate_method = :"generate_#{field}" max_attempts = .fetch(:max_attempts) { MAX_ATTEMPTS } after_create set_method, unless: :"#{field}?" # def self.generate_key define_singleton_method generate_method, &(block || DEFAULT_GENERATOR) # def set_key define_method(set_method) do attempt = 0 begin raise 'Available only for persisted record' unless persisted? transaction(requires_new: true) do new_value = self.class.send(generate_method, self) update_column field, new_value # rubocop:disable Rails/SkipsModelValidations end rescue ActiveRecord::RecordNotUnique attempt += 1 raise if attempt > max_attempts retry end end end |