sluggi 1.2.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96fa3f419d83aa9dd9df2699072fc12c8c3e786b45fcf8d19fe7adca90fd5438
4
- data.tar.gz: 853a52b8ff87cb5833a56ca6d889f2cecce7d56763e6d5c9fed2b1a91a806368
3
+ metadata.gz: 8defbc5cc0371b0519aa658cafe635cca4fdde6dc72f0467d461dbece5626271
4
+ data.tar.gz: 8fd633be45bf0a35cc4853ea625c5368e219db60b60cca90f749fdf5ac7646e1
5
5
  SHA512:
6
- metadata.gz: 4f135200b99655e4437f10e077355f84bdcbe5b474eb72148644a0b9b72fc43a3d3da38f78b6f45951a98fc41bbdf36d60a6b711c93767763ac4cf91937ad423
7
- data.tar.gz: edd20ee1f9d8d63c3e3d6a21e1d51fb229b5bf35510d2b53b6029cdbbc2eedbfcc35cd4d70a25a701db9cdfbf0cd71256602af5d540af54eef5dcfd7944a0f99
6
+ metadata.gz: 6b49d66d863cdf218f9df93fe4d15e608148e2e77b7c280f62b56ea3e48d2abeb97a63b66a5058e65854f5c302c5dad04871586e4a98b415745cddc57402a208
7
+ data.tar.gz: 7d8dbae0fe73f1ecabcee3587364cfaa88cf65080fb20d4e4b172bf47c1f6d87bd6d5dd4d48c694577ef24077afc6f1bb7d014b5cf7d6cea36d6e2fbb6d9c24f
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Gem Version](http://img.shields.io/gem/v/sluggi.svg)](http://rubygems.org/gems/sluggi)
4
4
  [![Build Status](http://img.shields.io/travis/neighborland/sluggi.svg)](https://travis-ci.org/neighborland/sluggi)
5
5
 
6
- Sluggi is a simple [friendly_id](https://github.com/norman/friendly_id)-inspired slugging library for ActiveRecord models.
6
+ Sluggi is a simple [friendly_id](https://github.com/norman/friendly_id)-inspired slugging library for ActiveRecord models. It is faster than `friendly_id` (see below for benchmarks).
7
7
 
8
8
  It provides basic slugs, slug history, and the ability to define multiple slug candidates.
9
9
 
@@ -129,20 +129,23 @@ Cat.find_by_slug('tuxedo-stan')
129
129
 
130
130
  ### Model with Slug Candidates
131
131
 
132
- Override `#slug_candidates` to define cascading candidate values for slugs. This is useful to avoid
133
- uniqueness conflicts.
132
+ Override `#slug_candidates` to define cascading candidate values for slugs.
133
+ This is useful to avoid uniqueness conflicts. Do not override `#slug_value` -
134
+ the default implementation in `Model` will call `#slug_candidates` and
135
+ works with or without `History`.
134
136
 
135
137
  ```ruby
136
138
  class Cat < ActiveRecord::Base
137
139
  include Sluggi::Slugged
138
140
 
139
- def name_and_id
140
- "#{name}-#{id}"
141
- end
142
-
143
- # the first unused value in the list is used
141
+ # The first unused value in the list is used.
142
+ # Each item may be a value or a lambda.
143
+ # Use a lambda to defer expensive unique value calculations.
144
144
  def slug_candidates
145
- [name, name_and_id]
145
+ [
146
+ name,
147
+ -> { "#{name}-#{Cat.count}" }
148
+ ]
146
149
  end
147
150
 
148
151
  def slug_value_changed?
@@ -158,11 +161,41 @@ cat.slug
158
161
 
159
162
  cat_2 = Cat.create(name: 'Tuxedo Stan')
160
163
  cat_2.slug
161
- => 'tuxedo-stan-2'
162
- cat_2.id
163
- => 2
164
+ => 'tuxedo-stan-456'
165
+ ```
166
+
167
+ ## Performance
168
+
169
+ Run the benchmark script: `ruby bench.rb`. This script is based on the
170
+ benchmark script from `friendly_id`.
171
+
172
+ Here are some anecdotal results using ruby 2.5.3:
164
173
 
165
174
  ```
175
+ SLUGGI FRIENDLY_ID
176
+ 1) find (id) - direct ActiveRecord 0.092318 0.093049
177
+ 2) find (in-table slug) 0.102773 0.259542
178
+ 3) find (in-table slug; using finders module) 0.098183 0.108248
179
+ 4) find (external slug) 0.670229 0.832791
180
+ 5) insert (plain AR / no slug) 0.345077 0.345105
181
+ 6) insert (in-table-slug) 0.666451 0.815505
182
+ 7) insert (in-table-slug; using finders module) 0.668737 0.744433
183
+ 8) insert (external slug) 2.480790 2.849761
184
+ ```
185
+
186
+ Notes:
187
+
188
+ Sluggi is at least 10% faster in every benchmark.
189
+
190
+ 1) Baseline (does not use either gem)
191
+ 2) 0.44x
192
+ 3) 0.90x
193
+ 4) 0.80x
194
+ 5) Baseline (does not use either gem)
195
+ 6) 0.82x
196
+ 7) 0.90x
197
+ 8) 0.87x
198
+
166
199
 
167
200
  ## Alternatives
168
201
 
@@ -39,11 +39,10 @@ module Sluggi
39
39
  end
40
40
 
41
41
  def create_slug
42
- value = clean_slug(slug_value)
43
- return if value.blank?
44
- return if slugs.first&.slug == value
45
- self.class.find_slugs(value).delete_all # revert to previous slug & put first
46
- slugs.create(slug: value)
42
+ return if slug.blank?
43
+ return if slugs.first&.slug == slug
44
+ self.class.find_slugs(slug).delete_all # revert to previous slug & put first
45
+ slugs.create(slug: slug)
47
46
  end
48
47
  end
49
48
  end
@@ -11,6 +11,13 @@ module Sluggi
11
11
  before_validation :set_slug
12
12
  end
13
13
 
14
+ module ClassMethods
15
+ # Define this so that History can override it.
16
+ def slug_exists?(name)
17
+ exists?(slug: name)
18
+ end
19
+ end
20
+
14
21
  def to_param
15
22
  errors.any? ? slug_was : slug
16
23
  end
@@ -31,11 +38,12 @@ module Sluggi
31
38
  # these are generally good to override:
32
39
 
33
40
  def slug_value
34
- slug_candidates.each do |value|
41
+ slug_candidates.each do |item|
42
+ value = item.respond_to?(:call) ? item.call : item
35
43
  next if value.blank?
36
44
  candidate = clean_slug(value)
37
45
  return candidate if candidate == slug
38
- return candidate unless self.class.exists?(slug: candidate)
46
+ return candidate unless self.class.slug_exists?(candidate)
39
47
  end
40
48
  nil
41
49
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sluggi
4
- VERSION = "1.2.0"
4
+ VERSION = "1.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sluggi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tee Parham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-21 00:00:00.000000000 Z
11
+ date: 2018-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord