friendly_id 5.5.0 → 5.6.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/.github/workflows/release.yml +29 -0
- data/.github/workflows/test.yml +33 -5
- data/.yardopts +2 -0
- data/Changelog.md +8 -1
- data/README.md +3 -3
- data/Rakefile +1 -5
- data/friendly_id.gemspec +2 -7
- data/gemfiles/{Gemfile.rails-5.2.rb → Gemfile.rails-7.1.rb} +4 -4
- data/gemfiles/Gemfile.rails-7.2.rb +22 -0
- data/gemfiles/Gemfile.rails-8.0.rb +22 -0
- data/guide.rb +9 -2
- data/lib/friendly_id/base.rb +4 -2
- data/lib/friendly_id/finders.rb +6 -3
- data/lib/friendly_id/history.rb +9 -6
- data/lib/friendly_id/reserved.rb +3 -1
- data/lib/friendly_id/scoped.rb +6 -4
- data/lib/friendly_id/simple_i18n.rb +8 -5
- data/lib/friendly_id/slug_generator.rb +15 -0
- data/lib/friendly_id/slugged.rb +33 -13
- data/lib/friendly_id/version.rb +1 -1
- data/lib/friendly_id.rb +6 -4
- data/test/helper.rb +2 -2
- data/test/numeric_slug_test.rb +69 -0
- metadata +11 -40
- checksums.yaml.gz.sig +0 -0
- data/certs/parndt.pem +0 -27
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41f8cc1c8668551a87b0537b5a30b812ec635755c7b1d0bfda678bc4be23b84c
|
|
4
|
+
data.tar.gz: 7cc6753a1f56537561558134ceae5c796b2e1296fa5230b0b734ddebd17be789
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cbfde34d6b2cd2347ab9837101824e65504fa226d51e4820e87b5cc7f2546c3e55decb2c7d0df4f8d1d899ef517f8177a5f63543a5577194071b7388f10cb5cf
|
|
7
|
+
data.tar.gz: f13c197800451a77c86092fa15fcd730ae669dca4486856ddf1dce21be7ad6ee8bbed41590f0a3afb1d72d804c343e4b5050f6c906090a7c951fb54b46c1d936
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Release to rubygems.org
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
push:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
environment: release
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v6
|
|
20
|
+
with:
|
|
21
|
+
persist-credentials: false
|
|
22
|
+
|
|
23
|
+
- name: Set up Ruby
|
|
24
|
+
uses: ruby/setup-ruby@v1
|
|
25
|
+
with:
|
|
26
|
+
bundler-cache: true
|
|
27
|
+
ruby-version: ruby
|
|
28
|
+
|
|
29
|
+
- uses: rubygems/release-gem@v1
|
data/.github/workflows/test.yml
CHANGED
|
@@ -10,11 +10,39 @@ jobs:
|
|
|
10
10
|
strategy:
|
|
11
11
|
matrix:
|
|
12
12
|
database: [ mysql, postgresql ]
|
|
13
|
-
gemfile: [ '7.0', '6.1', '6.0' ]
|
|
14
|
-
ruby: [ '2.
|
|
13
|
+
gemfile: [ '8.0', '7.2', '7.1', '7.0', '6.1', '6.0' ]
|
|
14
|
+
ruby: [ '2.7', '3.0', '3.1', '3.2', '3.3', '3.4' ]
|
|
15
15
|
exclude:
|
|
16
|
-
-
|
|
17
|
-
|
|
16
|
+
- gemfile: '6.0'
|
|
17
|
+
ruby: '3.2'
|
|
18
|
+
- gemfile: '6.0'
|
|
19
|
+
ruby: '3.3'
|
|
20
|
+
- gemfile: '6.0'
|
|
21
|
+
ruby: '3.4'
|
|
22
|
+
- gemfile: '6.1'
|
|
23
|
+
ruby: '3.2'
|
|
24
|
+
- gemfile: '6.1'
|
|
25
|
+
ruby: '3.3'
|
|
26
|
+
- gemfile: '6.1'
|
|
27
|
+
ruby: '3.4'
|
|
28
|
+
- gemfile: '7.0'
|
|
29
|
+
ruby: '3.3'
|
|
30
|
+
- gemfile: '7.0'
|
|
31
|
+
ruby: '3.4'
|
|
32
|
+
- gemfile: '7.1'
|
|
33
|
+
ruby: '3.3'
|
|
34
|
+
- gemfile: '7.1'
|
|
35
|
+
ruby: '3.4'
|
|
36
|
+
- gemfile: '7.2'
|
|
37
|
+
ruby: '2.7'
|
|
38
|
+
- gemfile: '7.2'
|
|
39
|
+
ruby: '3.0'
|
|
40
|
+
- gemfile: '8.0'
|
|
41
|
+
ruby: '2.7'
|
|
42
|
+
- gemfile: '8.0'
|
|
43
|
+
ruby: '3.0'
|
|
44
|
+
- gemfile: '8.0'
|
|
45
|
+
ruby: '3.1'
|
|
18
46
|
fail-fast: false
|
|
19
47
|
runs-on: ubuntu-latest
|
|
20
48
|
|
|
@@ -31,7 +59,7 @@ jobs:
|
|
|
31
59
|
|
|
32
60
|
name: ${{ matrix.ruby }} ${{ matrix.database }} rails-${{ matrix.gemfile }}
|
|
33
61
|
steps:
|
|
34
|
-
- uses: actions/checkout@
|
|
62
|
+
- uses: actions/checkout@v6
|
|
35
63
|
|
|
36
64
|
- run: sudo apt-get update && sudo apt-get install libsqlite3-dev -y
|
|
37
65
|
|
data/.yardopts
CHANGED
data/Changelog.md
CHANGED
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
We would like to think our many [contributors](https://github.com/norman/friendly_id/graphs/contributors) for
|
|
4
4
|
suggestions, ideas and improvements to FriendlyId.
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## 5.6.0 (2025-12-07)
|
|
7
|
+
|
|
8
|
+
* Add: `treat_numeric_as_conflict` option to prevent ambiguous numeric slugs. ([#1037](https://github.com/norman/friendly_id/pull/1037))
|
|
9
|
+
* Fix: history not using `parse_friendly_id`. ([#1020](https://github.com/norman/friendly_id/pull/1020))
|
|
10
|
+
|
|
11
|
+
## 5.5.1 (2023-11-13)
|
|
12
|
+
|
|
13
|
+
* Fix YARD doc generation. ([#1006](https://github.com/norman/friendly_id/pull/1006))
|
|
7
14
|
|
|
8
15
|
## 5.5.0 (2022-11-16)
|
|
9
16
|
|
data/README.md
CHANGED
|
@@ -39,7 +39,7 @@ FriendlyId offers many advanced features, including:
|
|
|
39
39
|
Add this line to your application's Gemfile:
|
|
40
40
|
|
|
41
41
|
```ruby
|
|
42
|
-
gem 'friendly_id', '~> 5.
|
|
42
|
+
gem 'friendly_id', '~> 5.5.0'
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
Note: You MUST use 5.0.0 or greater for Rails 4.0+.
|
|
@@ -108,8 +108,8 @@ User.find_each(&:save)
|
|
|
108
108
|
|
|
109
109
|
### `:allow_nil`
|
|
110
110
|
|
|
111
|
-
You can pass `allow_nil: true` to the `friendly.find()` method if you
|
|
112
|
-
avoid raising `ActiveRecord::RecordNotFound` and accept
|
|
111
|
+
You can pass `allow_nil: true` to the `friendly.find()` method if you want to
|
|
112
|
+
avoid raising `ActiveRecord::RecordNotFound` and accept `nil`.
|
|
113
113
|
|
|
114
114
|
#### Example
|
|
115
115
|
|
data/Rakefile
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "rubygems"
|
|
2
|
+
require "bundler/gem_tasks"
|
|
2
3
|
require "rake/testtask"
|
|
3
4
|
|
|
4
5
|
task default: :test
|
|
@@ -21,11 +22,6 @@ task :clean do
|
|
|
21
22
|
%x(rm -f `find . -name '*.rbc'`)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
desc "Build the gem"
|
|
25
|
-
task :gem do
|
|
26
|
-
`gem build friendly_id.gemspec`
|
|
27
|
-
end
|
|
28
|
-
|
|
29
25
|
desc "Build YARD documentation"
|
|
30
26
|
task :yard do
|
|
31
27
|
puts `bundle exec yard`
|
data/friendly_id.gemspec
CHANGED
|
@@ -4,7 +4,7 @@ Gem::Specification.new do |s|
|
|
|
4
4
|
s.name = "friendly_id"
|
|
5
5
|
s.version = FriendlyId::VERSION
|
|
6
6
|
s.authors = ["Norman Clarke", "Philip Arndt"]
|
|
7
|
-
s.email = ["norman@njclarke.com", "p
|
|
7
|
+
s.email = ["norman@njclarke.com", "gems@p.arndt.io"]
|
|
8
8
|
s.homepage = "https://github.com/norman/friendly_id"
|
|
9
9
|
s.summary = "A comprehensive slugging and pretty-URL plugin."
|
|
10
10
|
s.files = `git ls-files`.split("\n")
|
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.add_development_dependency "coveralls"
|
|
20
20
|
s.add_development_dependency "railties", ">= 4.0"
|
|
21
21
|
s.add_development_dependency "minitest", "~> 5.3"
|
|
22
|
-
s.add_development_dependency "mocha", "~>
|
|
22
|
+
s.add_development_dependency "mocha", "~> 2.1"
|
|
23
23
|
s.add_development_dependency "yard"
|
|
24
24
|
s.add_development_dependency "i18n"
|
|
25
25
|
s.add_development_dependency "ffaker"
|
|
@@ -28,9 +28,4 @@ Gem::Specification.new do |s|
|
|
|
28
28
|
s.description = "FriendlyId is the \"Swiss Army bulldozer\" of slugging " \
|
|
29
29
|
"and permalink plugins for Active Record. It lets you create pretty URLs " \
|
|
30
30
|
"and work with human-friendly strings as if they were numeric ids."
|
|
31
|
-
|
|
32
|
-
s.cert_chain = [File.expand_path("certs/parndt.pem", __dir__)]
|
|
33
|
-
if $PROGRAM_NAME.end_with?("gem") && ARGV.include?("build") && ARGV.include?(__FILE__)
|
|
34
|
-
s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem")
|
|
35
|
-
end
|
|
36
31
|
end
|
|
@@ -2,14 +2,14 @@ source "https://rubygems.org"
|
|
|
2
2
|
|
|
3
3
|
gemspec path: "../"
|
|
4
4
|
|
|
5
|
-
gem "activerecord", "~>
|
|
6
|
-
gem "railties", "~>
|
|
5
|
+
gem "activerecord", "~> 7.1.0"
|
|
6
|
+
gem "railties", "~> 7.1.0"
|
|
7
7
|
|
|
8
8
|
# Database Configuration
|
|
9
9
|
group :development, :test do
|
|
10
10
|
platforms :jruby do
|
|
11
|
-
gem "activerecord-jdbcmysql-adapter", "~>
|
|
12
|
-
gem "activerecord-jdbcpostgresql-adapter", "~>
|
|
11
|
+
gem "activerecord-jdbcmysql-adapter", "~> 61.0"
|
|
12
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
|
|
13
13
|
gem "kramdown"
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gemspec path: "../"
|
|
4
|
+
|
|
5
|
+
gem "activerecord", "~> 7.2.0"
|
|
6
|
+
gem "railties", "~> 7.2.0"
|
|
7
|
+
|
|
8
|
+
# Database Configuration
|
|
9
|
+
group :development, :test do
|
|
10
|
+
platforms :jruby do
|
|
11
|
+
gem "activerecord-jdbcmysql-adapter", "~> 61.0"
|
|
12
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
|
|
13
|
+
gem "kramdown"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
platforms :ruby, :rbx do
|
|
17
|
+
gem "sqlite3"
|
|
18
|
+
gem "mysql2"
|
|
19
|
+
gem "pg"
|
|
20
|
+
gem "redcarpet"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gemspec path: "../"
|
|
4
|
+
|
|
5
|
+
gem "activerecord", "~> 8.0.0"
|
|
6
|
+
gem "railties", "~> 8.0.0"
|
|
7
|
+
|
|
8
|
+
# Database Configuration
|
|
9
|
+
group :development, :test do
|
|
10
|
+
platforms :jruby do
|
|
11
|
+
gem "activerecord-jdbcmysql-adapter", "~> 61.0"
|
|
12
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
|
|
13
|
+
gem "kramdown"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
platforms :ruby, :rbx do
|
|
17
|
+
gem "sqlite3"
|
|
18
|
+
gem "mysql2"
|
|
19
|
+
gem "pg"
|
|
20
|
+
gem "redcarpet"
|
|
21
|
+
end
|
|
22
|
+
end
|
data/guide.rb
CHANGED
|
@@ -4,8 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
def comments_from path
|
|
6
6
|
path = File.expand_path("../lib/friendly_id/#{path}", __FILE__)
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
matches = File.read(path).match(/\n\s*# @guide begin\n(.*)\s*# @guide end/m)
|
|
8
|
+
|
|
9
|
+
return if matches.nil?
|
|
10
|
+
|
|
11
|
+
match = matches[1].to_s
|
|
12
|
+
match.split("\n")
|
|
13
|
+
.map { |x| x.sub(/^\s*#\s?/, "") } # Strip off the comment, leading whitespace, and the space after the comment
|
|
14
|
+
.reject { |x| x =~ /^@/ } # Ignore yarddoc tags for the guide
|
|
15
|
+
.join("\n").strip
|
|
9
16
|
end
|
|
10
17
|
|
|
11
18
|
File.open(File.expand_path("../Guide.md", __FILE__), "w:utf-8") do |guide|
|
data/lib/friendly_id/base.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module FriendlyId
|
|
2
|
+
# @guide begin
|
|
2
3
|
#
|
|
3
|
-
## Setting Up FriendlyId in Your Model
|
|
4
|
+
# ## Setting Up FriendlyId in Your Model
|
|
4
5
|
#
|
|
5
6
|
# To use FriendlyId in your ActiveRecord models, you must first either extend or
|
|
6
7
|
# include the FriendlyId module (it makes no difference), then invoke the
|
|
@@ -21,7 +22,7 @@ module FriendlyId
|
|
|
21
22
|
# all classes that participate in STI, both your parent classes and their
|
|
22
23
|
# children.*
|
|
23
24
|
#
|
|
24
|
-
### The Default Setup: Simple Models
|
|
25
|
+
# ### The Default Setup: Simple Models
|
|
25
26
|
#
|
|
26
27
|
# The simplest way to use FriendlyId is with a model that has a uniquely indexed
|
|
27
28
|
# column with no spaces or special characters, and that is seldom or never
|
|
@@ -53,6 +54,7 @@ module FriendlyId
|
|
|
53
54
|
# in a URL can be repetitive and surprisingly tricky, so for this reason it's
|
|
54
55
|
# often better and easier to use {FriendlyId::Slugged slugs}.
|
|
55
56
|
#
|
|
57
|
+
# @guide end
|
|
56
58
|
module Base
|
|
57
59
|
# Configure FriendlyId's behavior in a model.
|
|
58
60
|
#
|
data/lib/friendly_id/finders.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
module FriendlyId
|
|
2
|
+
# @guide begin
|
|
3
|
+
#
|
|
2
4
|
# ## Performing Finds with FriendlyId
|
|
3
5
|
#
|
|
4
6
|
# FriendlyId offers enhanced finders which will search for your record by
|
|
@@ -12,7 +14,7 @@ module FriendlyId
|
|
|
12
14
|
# Restaurant.find(23) #=> still works
|
|
13
15
|
# Restaurant.find('plaza-diner') #=> will not work
|
|
14
16
|
#
|
|
15
|
-
### Restoring FriendlyId 4.0-style finders
|
|
17
|
+
# ### Restoring FriendlyId 4.0-style finders
|
|
16
18
|
#
|
|
17
19
|
# Prior to version 5.0, FriendlyId overrode the default finder methods to perform
|
|
18
20
|
# friendly finds all the time. This required modifying parts of Rails that did
|
|
@@ -34,7 +36,7 @@ module FriendlyId
|
|
|
34
36
|
# Restaurant.find('plaza-diner') #=> now also works
|
|
35
37
|
# Restaurant.active.find('plaza-diner') #=> now also works
|
|
36
38
|
#
|
|
37
|
-
### Updating your application to use FriendlyId's finders
|
|
39
|
+
# ### Updating your application to use FriendlyId's finders
|
|
38
40
|
#
|
|
39
41
|
# Unless you've chosen to use the `:finders` addon, be sure to modify the finders
|
|
40
42
|
# in your controllers to use the `friendly` scope. For example:
|
|
@@ -49,7 +51,7 @@ module FriendlyId
|
|
|
49
51
|
# @restaurant = Restaurant.friendly.find(params[:id])
|
|
50
52
|
# end
|
|
51
53
|
#
|
|
52
|
-
#### Active Admin
|
|
54
|
+
# #### Active Admin
|
|
53
55
|
#
|
|
54
56
|
# Unless you use the `:finders` addon, you should modify your admin controllers
|
|
55
57
|
# for models that use FriendlyId with something similar to the following:
|
|
@@ -60,6 +62,7 @@ module FriendlyId
|
|
|
60
62
|
# end
|
|
61
63
|
# end
|
|
62
64
|
#
|
|
65
|
+
# @guide end
|
|
63
66
|
module Finders
|
|
64
67
|
module ClassMethods
|
|
65
68
|
if (ActiveRecord::VERSION::MAJOR == 4) && (ActiveRecord::VERSION::MINOR == 0)
|
data/lib/friendly_id/history.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module FriendlyId
|
|
2
|
+
# @guide begin
|
|
2
3
|
#
|
|
3
|
-
## History: Avoiding 404's When Slugs Change
|
|
4
|
+
# ## History: Avoiding 404's When Slugs Change
|
|
4
5
|
#
|
|
5
6
|
# FriendlyId's {FriendlyId::History History} module adds the ability to store a
|
|
6
7
|
# log of a model's slugs, so that when its friendly id changes, it's still
|
|
@@ -8,7 +9,7 @@ module FriendlyId
|
|
|
8
9
|
#
|
|
9
10
|
# The primary use case for this is avoiding broken URLs.
|
|
10
11
|
#
|
|
11
|
-
### Setup
|
|
12
|
+
# ### Setup
|
|
12
13
|
#
|
|
13
14
|
# In order to use this module, you must add a table to your database schema to
|
|
14
15
|
# store the slug records. FriendlyId provides a generator for this purpose:
|
|
@@ -19,13 +20,13 @@ module FriendlyId
|
|
|
19
20
|
# This will add a table named `friendly_id_slugs`, used by the {FriendlyId::Slug}
|
|
20
21
|
# model.
|
|
21
22
|
#
|
|
22
|
-
### Considerations
|
|
23
|
+
# ### Considerations
|
|
23
24
|
#
|
|
24
25
|
# Because recording slug history requires creating additional database records,
|
|
25
26
|
# this module has an impact on the performance of the associated model's `create`
|
|
26
27
|
# method.
|
|
27
28
|
#
|
|
28
|
-
### Example
|
|
29
|
+
# ### Example
|
|
29
30
|
#
|
|
30
31
|
# class Post < ActiveRecord::Base
|
|
31
32
|
# extend FriendlyId
|
|
@@ -49,6 +50,8 @@ module FriendlyId
|
|
|
49
50
|
# end
|
|
50
51
|
# end
|
|
51
52
|
# end
|
|
53
|
+
#
|
|
54
|
+
# @guide end
|
|
52
55
|
module History
|
|
53
56
|
module Configuration
|
|
54
57
|
def dependent_value
|
|
@@ -82,13 +85,13 @@ module FriendlyId
|
|
|
82
85
|
include ::FriendlyId::FinderMethods
|
|
83
86
|
|
|
84
87
|
def exists_by_friendly_id?(id)
|
|
85
|
-
super || joins(:slugs).where(slug_history_clause(id)).exists?
|
|
88
|
+
super || joins(:slugs).where(slug_history_clause(parse_friendly_id(id))).exists?
|
|
86
89
|
end
|
|
87
90
|
|
|
88
91
|
private
|
|
89
92
|
|
|
90
93
|
def first_by_friendly_id(id)
|
|
91
|
-
super || slug_table_record(id)
|
|
94
|
+
super || slug_table_record(parse_friendly_id(id))
|
|
92
95
|
end
|
|
93
96
|
|
|
94
97
|
def slug_table_record(id)
|
data/lib/friendly_id/reserved.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module FriendlyId
|
|
2
|
+
# @guide begin
|
|
2
3
|
#
|
|
3
|
-
## Reserved Words
|
|
4
|
+
# ## Reserved Words
|
|
4
5
|
#
|
|
5
6
|
# The {FriendlyId::Reserved Reserved} module adds the ability to exclude a list of
|
|
6
7
|
# words from use as FriendlyId slugs.
|
|
@@ -26,6 +27,7 @@ module FriendlyId
|
|
|
26
27
|
# end
|
|
27
28
|
# end
|
|
28
29
|
#
|
|
30
|
+
# @guide end
|
|
29
31
|
module Reserved
|
|
30
32
|
# When included, this module adds configuration options to the model class's
|
|
31
33
|
# friendly_id_config.
|
data/lib/friendly_id/scoped.rb
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
require "friendly_id/slugged"
|
|
2
2
|
|
|
3
3
|
module FriendlyId
|
|
4
|
+
# @guide begin
|
|
4
5
|
#
|
|
5
|
-
## Unique Slugs by Scope
|
|
6
|
+
# ## Unique Slugs by Scope
|
|
6
7
|
#
|
|
7
8
|
# The {FriendlyId::Scoped} module allows FriendlyId to generate unique slugs
|
|
8
9
|
# within a scope.
|
|
@@ -53,7 +54,7 @@ module FriendlyId
|
|
|
53
54
|
#
|
|
54
55
|
# All supplied values will be used to determine scope.
|
|
55
56
|
#
|
|
56
|
-
### Finding Records by Friendly ID
|
|
57
|
+
# ### Finding Records by Friendly ID
|
|
57
58
|
#
|
|
58
59
|
# If you are using scopes your friendly ids may not be unique, so a simple find
|
|
59
60
|
# like:
|
|
@@ -70,13 +71,13 @@ module FriendlyId
|
|
|
70
71
|
# Restaurant.where(:city_id => @city.id).friendly.find("joes-diner")
|
|
71
72
|
#
|
|
72
73
|
#
|
|
73
|
-
### Finding All Records That Match a Scoped ID
|
|
74
|
+
# ### Finding All Records That Match a Scoped ID
|
|
74
75
|
#
|
|
75
76
|
# Query the slug column directly:
|
|
76
77
|
#
|
|
77
78
|
# Restaurant.where(:slug => "joes-diner")
|
|
78
79
|
#
|
|
79
|
-
### Routes for Scoped Models
|
|
80
|
+
# ### Routes for Scoped Models
|
|
80
81
|
#
|
|
81
82
|
# Recall that FriendlyId is a database-centric library, and does not set up any
|
|
82
83
|
# routes for scoped models. You must do this yourself in your application. Here's
|
|
@@ -98,6 +99,7 @@ module FriendlyId
|
|
|
98
99
|
# http://example.org/cities/seattle/restaurants/joes-diner
|
|
99
100
|
# http://example.org/cities/chicago/restaurants/joes-diner
|
|
100
101
|
#
|
|
102
|
+
# @guide end
|
|
101
103
|
module Scoped
|
|
102
104
|
# FriendlyId::Config.use will invoke this method when present, to allow
|
|
103
105
|
# loading dependent modules prior to overriding them when necessary.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
require "i18n"
|
|
2
2
|
|
|
3
3
|
module FriendlyId
|
|
4
|
+
# @guide begin
|
|
4
5
|
#
|
|
5
|
-
## Translating Slugs Using Simple I18n
|
|
6
|
+
# ## Translating Slugs Using Simple I18n
|
|
6
7
|
#
|
|
7
8
|
# The {FriendlyId::SimpleI18n SimpleI18n} module adds very basic i18n support to
|
|
8
9
|
# FriendlyId.
|
|
@@ -17,7 +18,7 @@ module FriendlyId
|
|
|
17
18
|
# If you need to support two or more locales, you may wish to use the
|
|
18
19
|
# friendly_id_globalize gem instead.
|
|
19
20
|
#
|
|
20
|
-
### Example migration
|
|
21
|
+
# ### Example migration
|
|
21
22
|
#
|
|
22
23
|
# def self.up
|
|
23
24
|
# create_table :posts do |t|
|
|
@@ -32,7 +33,7 @@ module FriendlyId
|
|
|
32
33
|
# add_index :posts, :slug_pt_br
|
|
33
34
|
# end
|
|
34
35
|
#
|
|
35
|
-
### Finds
|
|
36
|
+
# ### Finds
|
|
36
37
|
#
|
|
37
38
|
# Finds will take into consideration the current locale:
|
|
38
39
|
#
|
|
@@ -50,11 +51,11 @@ module FriendlyId
|
|
|
50
51
|
# Post.friendly.find("la-guerra-de-las-galaxias")
|
|
51
52
|
# end
|
|
52
53
|
#
|
|
53
|
-
### Creating Records
|
|
54
|
+
# ### Creating Records
|
|
54
55
|
#
|
|
55
56
|
# When new records are created, the slug is generated for the current locale only.
|
|
56
57
|
#
|
|
57
|
-
### Translating Slugs
|
|
58
|
+
# ### Translating Slugs
|
|
58
59
|
#
|
|
59
60
|
# To translate an existing record's friendly_id, use
|
|
60
61
|
# {FriendlyId::SimpleI18n::Model#set_friendly_id}. This will ensure that the slug
|
|
@@ -69,6 +70,8 @@ module FriendlyId
|
|
|
69
70
|
# I18n.with_locale(:es) do
|
|
70
71
|
# post.set_friendly_id("La guerra de las galaxias")
|
|
71
72
|
# end
|
|
73
|
+
#
|
|
74
|
+
# @guide end
|
|
72
75
|
module SimpleI18n
|
|
73
76
|
# FriendlyId::Config.use will invoke this method when present, to allow
|
|
74
77
|
# loading dependent modules prior to overriding them when necessary.
|
|
@@ -12,6 +12,10 @@ module FriendlyId
|
|
|
12
12
|
return false if @config.reserved_words.include?(slug)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
if @config.treat_numeric_as_conflict && purely_numeric_slug?(slug)
|
|
16
|
+
return false
|
|
17
|
+
end
|
|
18
|
+
|
|
15
19
|
!@scope.exists_by_friendly_id?(slug)
|
|
16
20
|
end
|
|
17
21
|
|
|
@@ -19,5 +23,16 @@ module FriendlyId
|
|
|
19
23
|
candidates.each { |c| return c if available?(c) }
|
|
20
24
|
nil
|
|
21
25
|
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def purely_numeric_slug?(slug)
|
|
30
|
+
return false unless slug
|
|
31
|
+
begin
|
|
32
|
+
Integer(slug, 10).to_s == slug.to_s
|
|
33
|
+
rescue ArgumentError, TypeError
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
end
|
|
22
37
|
end
|
|
23
38
|
end
|
data/lib/friendly_id/slugged.rb
CHANGED
|
@@ -2,8 +2,9 @@ require "friendly_id/slug_generator"
|
|
|
2
2
|
require "friendly_id/candidates"
|
|
3
3
|
|
|
4
4
|
module FriendlyId
|
|
5
|
+
# @guide begin
|
|
5
6
|
#
|
|
6
|
-
## Slugged Models
|
|
7
|
+
# ## Slugged Models
|
|
7
8
|
#
|
|
8
9
|
# FriendlyId can use a separate column to store slugs for models which require
|
|
9
10
|
# some text processing.
|
|
@@ -34,7 +35,7 @@ module FriendlyId
|
|
|
34
35
|
# unique. You may also wish to constrain it to NOT NULL, but this depends on your
|
|
35
36
|
# app's behavior and requirements.
|
|
36
37
|
#
|
|
37
|
-
### Example Setup
|
|
38
|
+
# ### Example Setup
|
|
38
39
|
#
|
|
39
40
|
# # your model
|
|
40
41
|
# class Post < ActiveRecord::Base
|
|
@@ -60,9 +61,9 @@ module FriendlyId
|
|
|
60
61
|
# end
|
|
61
62
|
# end
|
|
62
63
|
#
|
|
63
|
-
### Working With Slugs
|
|
64
|
+
# ### Working With Slugs
|
|
64
65
|
#
|
|
65
|
-
#### Formatting
|
|
66
|
+
# #### Formatting
|
|
66
67
|
#
|
|
67
68
|
# By default, FriendlyId uses Active Support's
|
|
68
69
|
# [parameterize](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize)
|
|
@@ -72,7 +73,7 @@ module FriendlyId
|
|
|
72
73
|
# movie = Movie.create! :title => "Der Preis fürs Überleben"
|
|
73
74
|
# movie.slug #=> "der-preis-furs-uberleben"
|
|
74
75
|
#
|
|
75
|
-
#### Column or Method?
|
|
76
|
+
# #### Column or Method?
|
|
76
77
|
#
|
|
77
78
|
# FriendlyId always uses a method as the basis of the slug text - not a column. At
|
|
78
79
|
# first glance, this may sound confusing, but remember that Active Record provides
|
|
@@ -95,7 +96,7 @@ module FriendlyId
|
|
|
95
96
|
#
|
|
96
97
|
# FriendlyId refers to this internally as the "base" method.
|
|
97
98
|
#
|
|
98
|
-
#### Uniqueness
|
|
99
|
+
# #### Uniqueness
|
|
99
100
|
#
|
|
100
101
|
# When you try to insert a record that would generate a duplicate friendly id,
|
|
101
102
|
# FriendlyId will append a UUID to the generated slug to ensure uniqueness:
|
|
@@ -109,7 +110,7 @@ module FriendlyId
|
|
|
109
110
|
# Previous versions of FriendlyId appended a numeric sequence to make slugs
|
|
110
111
|
# unique, but this was removed to simplify using FriendlyId in concurrent code.
|
|
111
112
|
#
|
|
112
|
-
#### Candidates
|
|
113
|
+
# #### Candidates
|
|
113
114
|
#
|
|
114
115
|
# Since UUIDs are ugly, FriendlyId provides a "slug candidates" functionality to
|
|
115
116
|
# let you specify alternate slugs to use in the event the one you want to use is
|
|
@@ -147,20 +148,38 @@ module FriendlyId
|
|
|
147
148
|
# unique slug, then FriendlyId will append a UUID to the first candidate as a
|
|
148
149
|
# last resort.
|
|
149
150
|
#
|
|
150
|
-
#### Sequence Separator
|
|
151
|
+
# #### Sequence Separator
|
|
151
152
|
#
|
|
152
153
|
# By default, FriendlyId uses a dash to separate the slug from a sequence.
|
|
153
154
|
#
|
|
154
155
|
# You can change this with the {FriendlyId::Slugged::Configuration#sequence_separator
|
|
155
156
|
# sequence_separator} configuration option.
|
|
156
157
|
#
|
|
157
|
-
####
|
|
158
|
+
# #### Avoiding Numeric Slugs
|
|
159
|
+
#
|
|
160
|
+
# Purely numeric slugs like "123" can create ambiguity in Rails routing - they could
|
|
161
|
+
# be interpreted as either a friendly slug or a database ID. To prevent this, you can
|
|
162
|
+
# configure FriendlyId to treat numeric slugs as conflicts and add a UUID suffix:
|
|
163
|
+
#
|
|
164
|
+
# class Product < ActiveRecord::Base
|
|
165
|
+
# extend FriendlyId
|
|
166
|
+
# friendly_id :sku, use: :slugged
|
|
167
|
+
# friendly_id_config.treat_numeric_as_conflict = true
|
|
168
|
+
# end
|
|
169
|
+
#
|
|
170
|
+
# product = Product.create! sku: "123"
|
|
171
|
+
# product.slug #=> "123-f9f3789a-daec-4156-af1d-fab81aa16ee5"
|
|
172
|
+
#
|
|
173
|
+
# This only affects purely numeric slugs. Alphanumeric slugs like "product-123"
|
|
174
|
+
# or "abc123" will work normally.
|
|
175
|
+
#
|
|
176
|
+
# #### Providing Your Own Slug Processing Method
|
|
158
177
|
#
|
|
159
178
|
# You can override {FriendlyId::Slugged#normalize_friendly_id} in your model for
|
|
160
179
|
# total control over the slug format. It will be invoked for any generated slug,
|
|
161
180
|
# whether for a single slug or for slug candidates.
|
|
162
181
|
#
|
|
163
|
-
#### Deciding When to Generate New Slugs
|
|
182
|
+
# #### Deciding When to Generate New Slugs
|
|
164
183
|
#
|
|
165
184
|
# As of FriendlyId 5.0, slugs are only generated when the `slug` field is nil. If
|
|
166
185
|
# you want a slug to be regenerated,set the slug field to nil:
|
|
@@ -198,7 +217,7 @@ module FriendlyId
|
|
|
198
217
|
# end
|
|
199
218
|
# end
|
|
200
219
|
#
|
|
201
|
-
#### Locale-specific Transliterations
|
|
220
|
+
# #### Locale-specific Transliterations
|
|
202
221
|
#
|
|
203
222
|
# Active Support's `parameterize` uses
|
|
204
223
|
# [transliterate](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-transliterate),
|
|
@@ -219,7 +238,7 @@ module FriendlyId
|
|
|
219
238
|
#
|
|
220
239
|
# This functionality was in fact taken from earlier versions of FriendlyId.
|
|
221
240
|
#
|
|
222
|
-
#### Gotchas: Common Problems
|
|
241
|
+
# #### Gotchas: Common Problems
|
|
223
242
|
#
|
|
224
243
|
# FriendlyId uses a before_validation callback to generate and set the slug. This
|
|
225
244
|
# means that if you create two model instances before saving them, it's possible
|
|
@@ -233,6 +252,7 @@ module FriendlyId
|
|
|
233
252
|
# creating more than one nested record for a model that uses FriendlyId. See [this
|
|
234
253
|
# Github issue](https://github.com/norman/friendly_id/issues/185) for discussion.
|
|
235
254
|
#
|
|
255
|
+
# @guide end
|
|
236
256
|
module Slugged
|
|
237
257
|
# Sets up behavior and configuration options for FriendlyId's slugging
|
|
238
258
|
# feature.
|
|
@@ -384,7 +404,7 @@ module FriendlyId
|
|
|
384
404
|
# {FriendlyId::Configuration FriendlyId::Configuration}.
|
|
385
405
|
module Configuration
|
|
386
406
|
attr_writer :slug_column, :slug_limit, :sequence_separator
|
|
387
|
-
attr_accessor :slug_generator_class
|
|
407
|
+
attr_accessor :slug_generator_class, :treat_numeric_as_conflict
|
|
388
408
|
|
|
389
409
|
# Makes FriendlyId use the slug column for querying.
|
|
390
410
|
# @return String The slug column.
|
data/lib/friendly_id/version.rb
CHANGED
data/lib/friendly_id.rb
CHANGED
|
@@ -4,8 +4,9 @@ require "friendly_id/object_utils"
|
|
|
4
4
|
require "friendly_id/configuration"
|
|
5
5
|
require "friendly_id/finder_methods"
|
|
6
6
|
|
|
7
|
+
# @guide begin
|
|
7
8
|
#
|
|
8
|
-
## About FriendlyId
|
|
9
|
+
# ## About FriendlyId
|
|
9
10
|
#
|
|
10
11
|
# FriendlyId is an add-on to Ruby's Active Record that allows you to replace ids
|
|
11
12
|
# in your URLs with strings:
|
|
@@ -19,9 +20,9 @@ require "friendly_id/finder_methods"
|
|
|
19
20
|
# It requires few changes to your application code and offers flexibility,
|
|
20
21
|
# performance and a well-documented codebase.
|
|
21
22
|
#
|
|
22
|
-
### Core Concepts
|
|
23
|
+
# ### Core Concepts
|
|
23
24
|
#
|
|
24
|
-
#### Slugs
|
|
25
|
+
# #### Slugs
|
|
25
26
|
#
|
|
26
27
|
# The concept of *slugs* is at the heart of FriendlyId.
|
|
27
28
|
#
|
|
@@ -29,7 +30,7 @@ require "friendly_id/finder_methods"
|
|
|
29
30
|
# keywords, rather than an opaque identifier such as a numeric id. This can make
|
|
30
31
|
# your application more friendly both for users and search engines.
|
|
31
32
|
#
|
|
32
|
-
#### Finders: Slugs Act Like Numeric IDs
|
|
33
|
+
# #### Finders: Slugs Act Like Numeric IDs
|
|
33
34
|
#
|
|
34
35
|
# To the extent possible, FriendlyId lets you treat text-based identifiers like
|
|
35
36
|
# normal IDs. This means that you can perform finds with slugs just like you do
|
|
@@ -38,6 +39,7 @@ require "friendly_id/finder_methods"
|
|
|
38
39
|
# Person.find(82542335)
|
|
39
40
|
# Person.friendly.find("joe")
|
|
40
41
|
#
|
|
42
|
+
# @guide end
|
|
41
43
|
module FriendlyId
|
|
42
44
|
autoload :History, "friendly_id/history"
|
|
43
45
|
autoload :Slug, "friendly_id/slug"
|
data/test/helper.rb
CHANGED
data/test/numeric_slug_test.rb
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
require "helper"
|
|
2
2
|
|
|
3
|
+
class Article < ActiveRecord::Base
|
|
4
|
+
extend FriendlyId
|
|
5
|
+
friendly_id :name, use: :slugged
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class ArticleWithNumericPrevention < ActiveRecord::Base
|
|
9
|
+
self.table_name = "articles"
|
|
10
|
+
extend FriendlyId
|
|
11
|
+
friendly_id :name, use: :slugged
|
|
12
|
+
friendly_id_config.treat_numeric_as_conflict = true
|
|
13
|
+
end
|
|
14
|
+
|
|
3
15
|
class NumericSlugTest < TestCaseClass
|
|
4
16
|
include FriendlyId::Test
|
|
5
17
|
include FriendlyId::Test::Shared::Core
|
|
@@ -28,4 +40,61 @@ class NumericSlugTest < TestCaseClass
|
|
|
28
40
|
assert model_class.friendly.exists?("123")
|
|
29
41
|
end
|
|
30
42
|
end
|
|
43
|
+
|
|
44
|
+
test "should prevent purely numeric slugs when treat_numeric_as_conflict is enabled" do
|
|
45
|
+
transaction do
|
|
46
|
+
record = ArticleWithNumericPrevention.create! name: "123"
|
|
47
|
+
refute_equal "123", record.slug
|
|
48
|
+
assert_match(/\A123-[0-9a-f-]{36}\z/, record.slug)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test "should allow non-numeric slugs when treat_numeric_as_conflict is enabled" do
|
|
53
|
+
transaction do
|
|
54
|
+
record = ArticleWithNumericPrevention.create! name: "abc123"
|
|
55
|
+
assert_equal "abc123", record.slug
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test "should allow alphanumeric slugs when treat_numeric_as_conflict is enabled" do
|
|
60
|
+
transaction do
|
|
61
|
+
record = ArticleWithNumericPrevention.create! name: "product-123"
|
|
62
|
+
assert_equal "product-123", record.slug
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
test "should handle zero as numeric when treat_numeric_as_conflict is enabled" do
|
|
67
|
+
transaction do
|
|
68
|
+
record = ArticleWithNumericPrevention.create! name: "0"
|
|
69
|
+
refute_equal "0", record.slug
|
|
70
|
+
assert_match(/\A0-[0-9a-f-]{36}\z/, record.slug)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
test "should handle large numbers as numeric when treat_numeric_as_conflict is enabled" do
|
|
75
|
+
transaction do
|
|
76
|
+
record = ArticleWithNumericPrevention.create! name: "999999999"
|
|
77
|
+
refute_equal "999999999", record.slug
|
|
78
|
+
assert_match(/\A999999999-[0-9a-f-]{36}\z/, record.slug)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
test "should find records with UUID-suffixed numeric slugs when treat_numeric_as_conflict is enabled" do
|
|
83
|
+
transaction do
|
|
84
|
+
record = ArticleWithNumericPrevention.create! name: "123"
|
|
85
|
+
found = ArticleWithNumericPrevention.friendly.find(record.slug)
|
|
86
|
+
assert_equal record.id, found.id
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
test "should resolve conflicts between multiple numeric slugs when treat_numeric_as_conflict is enabled" do
|
|
91
|
+
transaction do
|
|
92
|
+
record1 = ArticleWithNumericPrevention.create! name: "456"
|
|
93
|
+
record2 = ArticleWithNumericPrevention.create! name: "456"
|
|
94
|
+
|
|
95
|
+
refute_equal record1.slug, record2.slug
|
|
96
|
+
assert_match(/\A456-[0-9a-f-]{36}\z/, record1.slug)
|
|
97
|
+
assert_match(/\A456-[0-9a-f-]{36}\z/, record2.slug)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
31
100
|
end
|
metadata
CHANGED
|
@@ -1,43 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: friendly_id
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Norman Clarke
|
|
8
8
|
- Philip Arndt
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
|
-
cert_chain:
|
|
12
|
-
-
|
|
13
|
-
-----BEGIN CERTIFICATE-----
|
|
14
|
-
MIIEljCCAv6gAwIBAgIBATANBgkqhkiG9w0BAQsFADBRMREwDwYDVQQDDAhydWJ5
|
|
15
|
-
Z2VtczERMA8GCgmSJomT8ixkARkWAXAxFTATBgoJkiaJk/IsZAEZFgVhcm5kdDES
|
|
16
|
-
MBAGCgmSJomT8ixkARkWAmlvMB4XDTIyMTExNTIyMjQzMFoXDTIzMTExNTIyMjQz
|
|
17
|
-
MFowUTERMA8GA1UEAwwIcnVieWdlbXMxETAPBgoJkiaJk/IsZAEZFgFwMRUwEwYK
|
|
18
|
-
CZImiZPyLGQBGRYFYXJuZHQxEjAQBgoJkiaJk/IsZAEZFgJpbzCCAaIwDQYJKoZI
|
|
19
|
-
hvcNAQEBBQADggGPADCCAYoCggGBAMPq2bIEO+BmmBeuidSySK7xlL/LWBHzyDxw
|
|
20
|
-
EMgWsHqJMDZYCZI4WoWbSTSSLrp5zPXLWN0hB23u3dxFp4RVygTTZkc8k05mteab
|
|
21
|
-
fdREGgdcP+mY8/ASQSvb1VW6IM51Srgjy1SK0S5Qf3HAiQafFvRsxRkY0SWyth24
|
|
22
|
-
ne/7HG667vHQ1+t0VFl8twupJE9S8p2zgX3eZBl2yRNm/kE5reUsOLvmS58Iri/X
|
|
23
|
-
9tnz0SGkzrKkim9OIByq7XkFLL3oaIyfbBVgOWilM5pvxj/xNuRH7EIM6aE3q0UZ
|
|
24
|
-
xo7o9u9Iz2zApDEjejByPjxWAhLuP3v3bJyinRFE1rO47lEM/s6KM/6YooxvgYIN
|
|
25
|
-
miYYFRtTj9nmKEMv6+h1mZ1/ZwqStTTRh/T90T65dcgsoqRd0JNvpNRjFrYH5cuj
|
|
26
|
-
QZWMl/FE6AADm0GXa34ZiTQx3Wx2ctqJLFak8+imPwes90nCpiYmgaZpwBI+shjU
|
|
27
|
-
AddbPDNq+EoxPMWTh0Er3w76fywOWQIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1Ud
|
|
28
|
-
DwQEAwIEsDAdBgNVHQ4EFgQUxRJaTQZmtkN8FKUWVHKc2riND18wHgYDVR0RBBcw
|
|
29
|
-
FYETcnVieWdlbXNAcC5hcm5kdC5pbzAeBgNVHRIEFzAVgRNydWJ5Z2Vtc0BwLmFy
|
|
30
|
-
bmR0LmlvMA0GCSqGSIb3DQEBCwUAA4IBgQBSRGMkZ2dvJ0LSjFz+rIt3G3AZMbKD
|
|
31
|
-
tjaaQRuC9rOkrl3Rml6h9j7cHYiM0wkTjXneFNySc8jWmM/jKnxiiUfUK9r1XL4n
|
|
32
|
-
71tz39+MD2lIpLVVEQ69MIoUseppNUTCg0mNghSDYNwISMD/hoWwbJudBi56DbhE
|
|
33
|
-
xkulLbw8qtcEE+iilIKibe+eJF4platKScsOA7d1AuilR1/S245UzeqwwyI52/xK
|
|
34
|
-
dfoP928X9Tb/48+83lWUgAgCQOd6WdfCpgQ5H6R90lc8L7OfuDR/vgcmSOTsNVgG
|
|
35
|
-
1TC3b2FISS0p0qfZsiS7BXh+ARoBKLXsV1a7WR36X0dUpajvk+zzBGrFCdbW43Gx
|
|
36
|
-
wmJzIksYnf9Ktg8Ux+FLcRBGw4qEIyWvqmS0obB1Hke68rTg0uNTFcKXsNw33XF5
|
|
37
|
-
fw1cbj95g7OPe0feGK8+afXh/L38vx/hIIOGlUEZ+HaWL2Dki/7vRGvda8dfOpG5
|
|
38
|
-
bJfaoyKbVsrK+gGKFJv860zsO8lg6BGLsUw=
|
|
39
|
-
-----END CERTIFICATE-----
|
|
40
|
-
date: 2022-11-15 00:00:00.000000000 Z
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
41
12
|
dependencies:
|
|
42
13
|
- !ruby/object:Gem::Dependency
|
|
43
14
|
name: activerecord
|
|
@@ -101,14 +72,14 @@ dependencies:
|
|
|
101
72
|
requirements:
|
|
102
73
|
- - "~>"
|
|
103
74
|
- !ruby/object:Gem::Version
|
|
104
|
-
version: '
|
|
75
|
+
version: '2.1'
|
|
105
76
|
type: :development
|
|
106
77
|
prerelease: false
|
|
107
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
108
79
|
requirements:
|
|
109
80
|
- - "~>"
|
|
110
81
|
- !ruby/object:Gem::Version
|
|
111
|
-
version: '
|
|
82
|
+
version: '2.1'
|
|
112
83
|
- !ruby/object:Gem::Dependency
|
|
113
84
|
name: yard
|
|
114
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -170,7 +141,7 @@ description: FriendlyId is the "Swiss Army bulldozer" of slugging and permalink
|
|
|
170
141
|
as if they were numeric ids.
|
|
171
142
|
email:
|
|
172
143
|
- norman@njclarke.com
|
|
173
|
-
- p
|
|
144
|
+
- gems@p.arndt.io
|
|
174
145
|
executables: []
|
|
175
146
|
extensions: []
|
|
176
147
|
extra_rdoc_files: []
|
|
@@ -179,6 +150,7 @@ files:
|
|
|
179
150
|
- ".github/FUNDING.yml"
|
|
180
151
|
- ".github/dependabot.yml"
|
|
181
152
|
- ".github/stale.yml"
|
|
153
|
+
- ".github/workflows/release.yml"
|
|
182
154
|
- ".github/workflows/test.yml"
|
|
183
155
|
- ".gitignore"
|
|
184
156
|
- ".yardopts"
|
|
@@ -190,12 +162,13 @@ files:
|
|
|
190
162
|
- Rakefile
|
|
191
163
|
- UPGRADING.md
|
|
192
164
|
- bench.rb
|
|
193
|
-
- certs/parndt.pem
|
|
194
165
|
- friendly_id.gemspec
|
|
195
|
-
- gemfiles/Gemfile.rails-5.2.rb
|
|
196
166
|
- gemfiles/Gemfile.rails-6.0.rb
|
|
197
167
|
- gemfiles/Gemfile.rails-6.1.rb
|
|
198
168
|
- gemfiles/Gemfile.rails-7.0.rb
|
|
169
|
+
- gemfiles/Gemfile.rails-7.1.rb
|
|
170
|
+
- gemfiles/Gemfile.rails-7.2.rb
|
|
171
|
+
- gemfiles/Gemfile.rails-8.0.rb
|
|
199
172
|
- guide.rb
|
|
200
173
|
- lib/friendly_id.rb
|
|
201
174
|
- lib/friendly_id/.gitattributes
|
|
@@ -243,7 +216,6 @@ homepage: https://github.com/norman/friendly_id
|
|
|
243
216
|
licenses:
|
|
244
217
|
- MIT
|
|
245
218
|
metadata: {}
|
|
246
|
-
post_install_message:
|
|
247
219
|
rdoc_options: []
|
|
248
220
|
require_paths:
|
|
249
221
|
- lib
|
|
@@ -258,8 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
258
230
|
- !ruby/object:Gem::Version
|
|
259
231
|
version: '0'
|
|
260
232
|
requirements: []
|
|
261
|
-
rubygems_version: 3.
|
|
262
|
-
signing_key:
|
|
233
|
+
rubygems_version: 3.6.9
|
|
263
234
|
specification_version: 4
|
|
264
235
|
summary: A comprehensive slugging and pretty-URL plugin.
|
|
265
236
|
test_files: []
|
checksums.yaml.gz.sig
DELETED
|
Binary file
|
data/certs/parndt.pem
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
|
2
|
-
MIIEljCCAv6gAwIBAgIBATANBgkqhkiG9w0BAQsFADBRMREwDwYDVQQDDAhydWJ5
|
|
3
|
-
Z2VtczERMA8GCgmSJomT8ixkARkWAXAxFTATBgoJkiaJk/IsZAEZFgVhcm5kdDES
|
|
4
|
-
MBAGCgmSJomT8ixkARkWAmlvMB4XDTIyMTExNTIyMjQzMFoXDTIzMTExNTIyMjQz
|
|
5
|
-
MFowUTERMA8GA1UEAwwIcnVieWdlbXMxETAPBgoJkiaJk/IsZAEZFgFwMRUwEwYK
|
|
6
|
-
CZImiZPyLGQBGRYFYXJuZHQxEjAQBgoJkiaJk/IsZAEZFgJpbzCCAaIwDQYJKoZI
|
|
7
|
-
hvcNAQEBBQADggGPADCCAYoCggGBAMPq2bIEO+BmmBeuidSySK7xlL/LWBHzyDxw
|
|
8
|
-
EMgWsHqJMDZYCZI4WoWbSTSSLrp5zPXLWN0hB23u3dxFp4RVygTTZkc8k05mteab
|
|
9
|
-
fdREGgdcP+mY8/ASQSvb1VW6IM51Srgjy1SK0S5Qf3HAiQafFvRsxRkY0SWyth24
|
|
10
|
-
ne/7HG667vHQ1+t0VFl8twupJE9S8p2zgX3eZBl2yRNm/kE5reUsOLvmS58Iri/X
|
|
11
|
-
9tnz0SGkzrKkim9OIByq7XkFLL3oaIyfbBVgOWilM5pvxj/xNuRH7EIM6aE3q0UZ
|
|
12
|
-
xo7o9u9Iz2zApDEjejByPjxWAhLuP3v3bJyinRFE1rO47lEM/s6KM/6YooxvgYIN
|
|
13
|
-
miYYFRtTj9nmKEMv6+h1mZ1/ZwqStTTRh/T90T65dcgsoqRd0JNvpNRjFrYH5cuj
|
|
14
|
-
QZWMl/FE6AADm0GXa34ZiTQx3Wx2ctqJLFak8+imPwes90nCpiYmgaZpwBI+shjU
|
|
15
|
-
AddbPDNq+EoxPMWTh0Er3w76fywOWQIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1Ud
|
|
16
|
-
DwQEAwIEsDAdBgNVHQ4EFgQUxRJaTQZmtkN8FKUWVHKc2riND18wHgYDVR0RBBcw
|
|
17
|
-
FYETcnVieWdlbXNAcC5hcm5kdC5pbzAeBgNVHRIEFzAVgRNydWJ5Z2Vtc0BwLmFy
|
|
18
|
-
bmR0LmlvMA0GCSqGSIb3DQEBCwUAA4IBgQBSRGMkZ2dvJ0LSjFz+rIt3G3AZMbKD
|
|
19
|
-
tjaaQRuC9rOkrl3Rml6h9j7cHYiM0wkTjXneFNySc8jWmM/jKnxiiUfUK9r1XL4n
|
|
20
|
-
71tz39+MD2lIpLVVEQ69MIoUseppNUTCg0mNghSDYNwISMD/hoWwbJudBi56DbhE
|
|
21
|
-
xkulLbw8qtcEE+iilIKibe+eJF4platKScsOA7d1AuilR1/S245UzeqwwyI52/xK
|
|
22
|
-
dfoP928X9Tb/48+83lWUgAgCQOd6WdfCpgQ5H6R90lc8L7OfuDR/vgcmSOTsNVgG
|
|
23
|
-
1TC3b2FISS0p0qfZsiS7BXh+ARoBKLXsV1a7WR36X0dUpajvk+zzBGrFCdbW43Gx
|
|
24
|
-
wmJzIksYnf9Ktg8Ux+FLcRBGw4qEIyWvqmS0obB1Hke68rTg0uNTFcKXsNw33XF5
|
|
25
|
-
fw1cbj95g7OPe0feGK8+afXh/L38vx/hIIOGlUEZ+HaWL2Dki/7vRGvda8dfOpG5
|
|
26
|
-
bJfaoyKbVsrK+gGKFJv860zsO8lg6BGLsUw=
|
|
27
|
-
-----END CERTIFICATE-----
|
data.tar.gz.sig
DELETED
|
Binary file
|
metadata.gz.sig
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
j搉g6hDŽ���aQ�,��[�H�+P~M@ɈLO�z�!�TV�ٿ��>q|0T����ع|cDs1�`�����5�ϝd+��������\�:Ƶ���T��5��;�P��j]��h'�D�+�H-��@z}�,��WR) w���%�t�I�?L�4ɚ4K��뜂HI`4X
|