happy_slugs 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f1ac5958a40f6b82ef5a800d2c8254db0ca51e0d7d366175fd8acab9a321fb8e
4
+ data.tar.gz: a54fe1b412133a631f06d747cb8945a60be397f7bba55464fecb3842696e9a0e
5
+ SHA512:
6
+ metadata.gz: e20e9a4ae93bdeed91a611299a0b2fd11215c745a6c1ea5899000ed7013558b5eca71f099b3e735c0119cd8c4c5bdd2c7ef99df9cc4dd1195dd8f3af60bfb1d0
7
+ data.tar.gz: 12b1219f5b002108ba2e2a3269c79d3b7b2ff22008fd51d7b2c4586a3395c39a5a1a9dbe9caef7707f149bc00adbef6a665e1f6e8c44fd23ff5a3a85f715e662
@@ -0,0 +1,3 @@
1
+ module HappySlugs
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,88 @@
1
+ module HappySlugs
2
+ module Words
3
+ ADJECTIVES = %w[
4
+ afraid all beige better big blue bold brave breezy bright brown bumpy
5
+ busy calm chatty chilly chubby clean clear clever cold common cool cozy
6
+ crisp cuddly curly curvy cute cyan dark deep dirty dry dull eager early
7
+ easy eight eighty eleven empty every fair famous fancy fast few fiery
8
+ fifty fine five flat floppy fluffy forty four frank free fresh fruity
9
+ full funky funny fuzzy gentle giant gold good goofy great green grumpy
10
+ happy heavy hip honest hot huge humble hungry icy itchy jolly khaki kind
11
+ large late lazy legal lemon light little long loose loud lovely lucky
12
+ major many metal mighty modern moody neat new nice nine ninety odd old
13
+ olive open orange perky petite pink plain plenty polite pretty proud
14
+ public puny purple quick quiet rare ready real red rich ripe salty seven
15
+ shaggy shaky sharp shiny short shy silent silly silver six sixty slick
16
+ slimy slow small smart smooth social soft solid some sour sparkly spicy
17
+ spotty stale strict strong sunny sweet swift tall tame tangy tasty ten
18
+ tender thick thin thirty three tidy tiny tired tough tricky true twelve
19
+ twenty two upset vast violet wacky warm wet whole wicked wide wild wise
20
+ witty yellow young yummy
21
+ ].freeze
22
+
23
+ NOUNS = %w[
24
+ actors ads adults aliens animals ants apes apples areas baboons badgers
25
+ bags balloons bananas banks bars baths bats beans bears beds beers bees
26
+ berries bikes birds boats bobcats books bottles boxes breads brooms
27
+ buckets bugs buses bushes buttons camels cameras candies candles canyons
28
+ carpets carrots cars cases cats chairs chefs chicken cities clocks cloths
29
+ clouds clowns clubs coats cobras coins colts comics cooks corners cougars
30
+ cows crabs crews cups cycles dancers days deer deserts dingos dodos dogs
31
+ dolls donkeys donuts doodles doors dots dragons drinks dryers ducks eagles
32
+ ears eels eggs emus ends experts eyes facts falcons fans feet files flies
33
+ flowers forks foxes friends frogs games garlics geckos geese ghosts gifts
34
+ glasses goats grapes groups guests hairs hands hats heads hoops hornets
35
+ horses hotels hounds houses humans icons ideas impalas insects islands
36
+ items jars jeans jobs jokes keys kids kings kiwis knives lamps lands laws
37
+ lemons lies lights lilies lines lions lizards llamas loops mails mammals
38
+ mangos maps masks meals melons memes meteors mice mirrors moles moments
39
+ monkeys months moons moose mugs nails needles news nights numbers olives
40
+ onions oranges otters owls pandas pans pants papayas papers parents parks
41
+ parrots parts paths paws peaches pears peas pens pets phones pianos pigs
42
+ pillows places planes planets plants plums poems poets points pots pugs
43
+ pumas queens rabbits radios rats ravens readers regions results rice rings
44
+ rivers rockets rocks rooms roses rules sails schools seals seas sheep
45
+ shirts shoes showers shrimps sides signs singers sites sloths snails
46
+ snakes socks spiders spies spoons squids stamps stars states steaks
47
+ streets suits suns swans symbols tables taxes taxis teams teeth terms
48
+ things ties tigers times tips tires toes tools towns toys trains trams
49
+ trees turkeys turtles vans views walls wasps waves ways webs weeks
50
+ windows wings wolves wombats words worlds worms yaks years zebras zoos
51
+ ].freeze
52
+
53
+ VERBS = %w[
54
+ accept act add admire agree allow appear argue arrive ask attack attend
55
+ bake bathe battle beam beg begin behave bet boil bow brake brush build
56
+ burn buy call camp care carry change cheat check cheer chew clap clean
57
+ cough count cover crash create cross cry cut dance decide deny design dig
58
+ divide do double doubt draw dream dress drive drop drum eat end enjoy
59
+ enter exist fail fall feel fetch film find fix flash float flow fly fold
60
+ follow fry give glow go grab greet grin grow guess hammer hang happen
61
+ heal hear help hide hope hug hunt invent invite itch jam jog join joke
62
+ judge juggle jump kick kiss kneel knock know laugh lay lead learn leave
63
+ lick lie like listen live look lose love make march marry mate matter
64
+ melt mix move nail notice obey occur open own pay peel pick play poke
65
+ post press prove pull pump punch push raise read refuse relate relax
66
+ remain repair repeat reply report rescue rest retire return rhyme ring
67
+ roll rule run rush say scream search see sell send serve shake share
68
+ shave shine shop shout show sin sing sink sip sit sleep slide smash smell
69
+ smile smoke sneeze sniff sort speak spend stand stare start stay stick
70
+ stop strive study swim switch take talk tan tap taste teach tease tell
71
+ thank think throw tickle tie trade train travel try turn type unite
72
+ vanish visit wait walk warn wash watch wave wear win wink wish wonder
73
+ work worry write yawn yell
74
+ ].freeze
75
+
76
+ ADVERBS = %w[
77
+ bravely brightly busily daily freely hungrily joyously knowingly lazily
78
+ noisily oddly politely quickly quietly rapidly safely sleepily slowly
79
+ truly yearly
80
+ ].freeze
81
+
82
+ LISTS = { adjective: ADJECTIVES, noun: NOUNS, verb: VERBS, adverb: ADVERBS }.freeze
83
+
84
+ def self.sample(type)
85
+ LISTS.fetch(type).sample
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,89 @@
1
+ require "active_record"
2
+ require "securerandom"
3
+ require_relative "happy_slugs/version"
4
+ require_relative "happy_slugs/words"
5
+
6
+ module HappySlugs
7
+ class ExhaustedError < StandardError; end
8
+
9
+ DEFAULT_PATTERN = %i[adjective noun verb].freeze
10
+ BATCH_SIZE = 10
11
+
12
+ module SlugGenerator
13
+ extend ActiveSupport::Concern
14
+
15
+ included do
16
+ before_create :generate_happy_slug
17
+ scope :with_happy_slug_in, ->(slugs) { where(happy_slug_attribute => slugs) }
18
+ end
19
+
20
+ def happy_slug
21
+ self[happy_slug_attribute]
22
+ end
23
+
24
+ private
25
+
26
+ def generate_happy_slug
27
+ if happy_slug.nil?
28
+ happy_slug_patterns.each do |pattern|
29
+ candidates = BATCH_SIZE.times.map { build_happy_slug(pattern) }
30
+ existing = self.class.with_happy_slug_in(candidates).pluck(happy_slug_attribute)
31
+
32
+ available = candidates - existing
33
+
34
+ if available.any?
35
+ self[happy_slug_attribute] = available.sample
36
+ break
37
+ end
38
+ end
39
+ end
40
+
41
+ if happy_slug.nil?
42
+ raise ExhaustedError, "could not generate a unique slug for #{self.class.name}"
43
+ end
44
+ end
45
+
46
+ def happy_slug_patterns
47
+ [happy_slug_pattern, happy_slug_pattern + [:suffix]].uniq
48
+ end
49
+
50
+ def build_happy_slug(pattern)
51
+ pattern.map { |segment|
52
+ if segment == :suffix
53
+ SecureRandom.alphanumeric(happy_slug_suffix_length).downcase
54
+ else
55
+ Words.sample(segment)
56
+ end
57
+ }.join(happy_slug_separator)
58
+ end
59
+
60
+ class_methods do
61
+ def backfill_happy_slugs
62
+ count = 0
63
+ where(happy_slug_attribute => nil).find_each do |record|
64
+ record.send(:generate_happy_slug)
65
+ record.update_column(happy_slug_attribute, record[happy_slug_attribute])
66
+ count += 1
67
+ rescue ActiveRecord::RecordNotUnique => e
68
+ raise unless e.message.include?(happy_slug_attribute.to_s)
69
+ record[happy_slug_attribute] = nil
70
+ retry
71
+ end
72
+ count
73
+ end
74
+ end
75
+ end
76
+
77
+ def has_happy_slugs(attribute = :slug, pattern: DEFAULT_PATTERN, separator: "-", suffix_length: 4)
78
+ class_attribute :happy_slug_attribute, default: attribute
79
+ class_attribute :happy_slug_pattern, default: pattern
80
+ class_attribute :happy_slug_separator, default: separator
81
+ class_attribute :happy_slug_suffix_length, default: suffix_length
82
+
83
+ include SlugGenerator
84
+ end
85
+ end
86
+
87
+ ActiveSupport.on_load(:active_record) do
88
+ extend HappySlugs
89
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: happy_slugs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Carl Dawson
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: activerecord
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '7.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '7.0'
26
+ executables: []
27
+ extensions: []
28
+ extra_rdoc_files: []
29
+ files:
30
+ - lib/happy_slugs.rb
31
+ - lib/happy_slugs/version.rb
32
+ - lib/happy_slugs/words.rb
33
+ homepage: https://github.com/carldaws/happy_slugs
34
+ licenses:
35
+ - MIT
36
+ metadata:
37
+ homepage_uri: https://github.com/carldaws/happy_slugs
38
+ source_code_uri: https://github.com/carldaws/happy_slugs
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '3.1'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubygems_version: 4.0.3
54
+ specification_version: 4
55
+ summary: Pleasant, random, human-readable slugs for ActiveRecord models
56
+ test_files: []