acts_as_permalink 1.2.0 → 1.2.1
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/MIT-LICENSE +1 -1
- data/README.md +18 -2
- data/lib/acts_as_permalink.rb +1 -71
- data/lib/acts_as_permalink/version.rb +1 -1
- data/lib/base.rb +5 -0
- data/lib/concern.rb +67 -0
- data/lib/conversion.rb +19 -0
- data/lib/string.rb +1 -11
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d55be1df515e3a84a052fda0f34d2889d1c5969
|
4
|
+
data.tar.gz: ef5a117a72ff179f479bb51dd21be2ec5c086ba0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ba4be9a30fe6aa69be591befc022df3b6107c46371fe6f1d5daaae6fd15bec50666709dc3b1d7b2a2a1fadfcf815b4b6d163a8bebc43f91f08749b562a0d093
|
7
|
+
data.tar.gz: 8d3c9bd3cde2c57c90b90ea1c2214db561dceacc089cf61249376c923dd55084447cbc0d63c48fddf198f68c7d9c21f19156b8185c8e1830290a5533d79a4927
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
Manages permalink field on an ActiveRecord model to be used in place of the id field in Rails.
|
6
6
|
|
7
|
-
|
7
|
+
[Kevin McPhillips](https://github.com/kmcphillips) ([github@kevinmcphillips.ca](mailto:github@kevinmcphillips.ca))
|
8
8
|
|
9
9
|
|
10
10
|
## Installation
|
@@ -29,7 +29,7 @@ $ gem install acts_as_permalink
|
|
29
29
|
|
30
30
|
## Usage
|
31
31
|
|
32
|
-
This gem works with ActiveRecord
|
32
|
+
This gem works with `ActiveRecord`, and by convention looks for a `title` method and a `permalink` string field on the model:
|
33
33
|
|
34
34
|
And then just call it in your model:
|
35
35
|
|
@@ -68,6 +68,20 @@ class User < ActiveRecord::Base
|
|
68
68
|
end
|
69
69
|
```
|
70
70
|
|
71
|
+
Permalinks can be generated using `String#to_permalink` like so:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
"Hello, world!".to_permalink
|
75
|
+
> "hello_world"
|
76
|
+
```
|
77
|
+
|
78
|
+
And the patch to string can be avoided by doing a `require: "base"` in the `Gemfile` of the application. Conversion is always available through:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
Acts::Permalink::Conversion.convert("Hello, world!")
|
82
|
+
> "hello_world"
|
83
|
+
```
|
84
|
+
|
71
85
|
|
72
86
|
## Tests
|
73
87
|
|
@@ -78,6 +92,8 @@ $ bundle exec rspec
|
|
78
92
|
|
79
93
|
## Changelog
|
80
94
|
|
95
|
+
* 1.2.1 -- Separate out `String#to_permalink` patch. Can `require: 'base'`.
|
96
|
+
|
81
97
|
* 1.2.0 -- Add the `allow_update` flag. (by @garethson)
|
82
98
|
|
83
99
|
* 1.1.0 -- Allow the option to `scope: :column_id` for uniquness.
|
data/lib/acts_as_permalink.rb
CHANGED
@@ -1,72 +1,2 @@
|
|
1
1
|
require "string"
|
2
|
-
require "
|
3
|
-
|
4
|
-
module Acts
|
5
|
-
module Permalink
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
class_methods do
|
9
|
-
def acts_as_permalink(options={})
|
10
|
-
cattr_accessor :acts_as_permalink_config
|
11
|
-
self.acts_as_permalink_config = Acts::Permalink::Config.new(options)
|
12
|
-
|
13
|
-
before_validation :update_permalink, on: :create
|
14
|
-
|
15
|
-
unless self.acts_as_permalink_config.allow_update
|
16
|
-
attr_readonly self.acts_as_permalink_config.to
|
17
|
-
end
|
18
|
-
|
19
|
-
if self.acts_as_permalink_config.scope
|
20
|
-
validates self.acts_as_permalink_config.to, uniqueness: {scope: self.acts_as_permalink_config.scope}
|
21
|
-
else
|
22
|
-
validates self.acts_as_permalink_config.to, uniqueness: true
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
|
-
include Acts::Permalink::InstanceMethods
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
module InstanceMethods
|
31
|
-
def to_param
|
32
|
-
self.public_send(self.class.base_class.acts_as_permalink_config.to)
|
33
|
-
end
|
34
|
-
|
35
|
-
def update_permalink
|
36
|
-
self.public_send("#{ self.class.base_class.acts_as_permalink_config.to }=", build_permalink)
|
37
|
-
true
|
38
|
-
end
|
39
|
-
|
40
|
-
def build_permalink
|
41
|
-
config = self.class.base_class.acts_as_permalink_config
|
42
|
-
|
43
|
-
text = self.public_send(config.from)
|
44
|
-
text = [self.class.base_class.to_s, rand(10000)].join(config.separator) if text.blank?
|
45
|
-
text = text.to_permalink(separator: config.separator, max_length: config.max_length)
|
46
|
-
|
47
|
-
# scope it if one is present
|
48
|
-
conditions = {}
|
49
|
-
conditions[config.scope] = self.public_send(config.scope) if config.scope.present?
|
50
|
-
|
51
|
-
# Attempt to find the object by the permalink, and if so there is a collision and we need to de-collision it
|
52
|
-
if self.class.base_class.where(conditions.merge(config.to => text)).any?
|
53
|
-
candidate_text = nil
|
54
|
-
|
55
|
-
# This will fail if you have a million records with the same name
|
56
|
-
(1..999999).each do |num|
|
57
|
-
suffix = "#{ config.separator }#{ num }"
|
58
|
-
candidate_text = [text[0...(config.max_length - suffix.length)], suffix].join("")
|
59
|
-
break unless self.class.base_class.where(conditions.merge(config.to => candidate_text)).any?
|
60
|
-
end
|
61
|
-
|
62
|
-
text = candidate_text
|
63
|
-
end
|
64
|
-
|
65
|
-
text
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
ActiveRecord::Base.send(:include, Acts::Permalink)
|
2
|
+
require "base"
|
data/lib/base.rb
ADDED
data/lib/concern.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
module Acts
|
2
|
+
module Permalink
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
def acts_as_permalink(options={})
|
7
|
+
cattr_accessor :acts_as_permalink_config
|
8
|
+
self.acts_as_permalink_config = Acts::Permalink::Config.new(options)
|
9
|
+
|
10
|
+
before_validation :update_permalink, on: :create
|
11
|
+
|
12
|
+
unless self.acts_as_permalink_config.allow_update
|
13
|
+
attr_readonly self.acts_as_permalink_config.to
|
14
|
+
end
|
15
|
+
|
16
|
+
if self.acts_as_permalink_config.scope
|
17
|
+
validates self.acts_as_permalink_config.to, uniqueness: {scope: self.acts_as_permalink_config.scope}
|
18
|
+
else
|
19
|
+
validates self.acts_as_permalink_config.to, uniqueness: true
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
include Acts::Permalink::InstanceMethods
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module InstanceMethods
|
28
|
+
def to_param
|
29
|
+
self.public_send(self.class.base_class.acts_as_permalink_config.to)
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_permalink
|
33
|
+
self.public_send("#{ self.class.base_class.acts_as_permalink_config.to }=", build_permalink)
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_permalink
|
38
|
+
config = self.class.base_class.acts_as_permalink_config
|
39
|
+
|
40
|
+
text = self.public_send(config.from)
|
41
|
+
text = [self.class.base_class.to_s, rand(10000)].join(config.separator) if text.blank?
|
42
|
+
text = Acts::Permalink::Conversion.convert(text, separator: config.separator, max_length: config.max_length)
|
43
|
+
|
44
|
+
# scope it if one is present
|
45
|
+
conditions = {}
|
46
|
+
conditions[config.scope] = self.public_send(config.scope) if config.scope.present?
|
47
|
+
|
48
|
+
# Attempt to find the object by the permalink, and if so there is a collision and we need to de-collision it
|
49
|
+
if self.class.base_class.where(conditions.merge(config.to => text)).any?
|
50
|
+
candidate_text = nil
|
51
|
+
|
52
|
+
# This will fail if you have a million records with the same name
|
53
|
+
(1..999999).each do |num|
|
54
|
+
suffix = "#{ config.separator }#{ num }"
|
55
|
+
candidate_text = [text[0...(config.max_length - suffix.length)], suffix].join("")
|
56
|
+
break unless self.class.base_class.where(conditions.merge(config.to => candidate_text)).any?
|
57
|
+
end
|
58
|
+
|
59
|
+
text = candidate_text
|
60
|
+
end
|
61
|
+
|
62
|
+
text
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/lib/conversion.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Acts
|
2
|
+
module Permalink
|
3
|
+
module Conversion
|
4
|
+
class << self
|
5
|
+
def convert(string, max_length: nil, separator: "-")
|
6
|
+
string = ActiveSupport::Inflector.transliterate(string) # convert to simplified characters
|
7
|
+
string = string.downcase.strip # make the string lowercase and scrub white space on either side
|
8
|
+
string = string.gsub(/[^a-z0-9]/, separator) # make any character that is not nupermic or alphabetic into a special character
|
9
|
+
string = string.squeeze(separator) # removes any consecutive duplicates of the special character
|
10
|
+
string = string.sub(Regexp.new("^#{ separator }+"), "") # remove leading special characters
|
11
|
+
string = string.sub(Regexp.new("#{ separator }+$"), "") # remove trailing special characters
|
12
|
+
string = string[0...max_length] if max_length # trim to length
|
13
|
+
|
14
|
+
string
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/string.rb
CHANGED
@@ -1,15 +1,5 @@
|
|
1
1
|
class String
|
2
2
|
def to_permalink(max_length: nil, separator: "-")
|
3
|
-
|
4
|
-
|
5
|
-
text = ActiveSupport::Inflector.transliterate(text) # convert to simplified characters
|
6
|
-
text = text.downcase.strip # make the string lowercase and scrub white space on either side
|
7
|
-
text = text.gsub(/[^a-z0-9]/, separator) # make any character that is not nupermic or alphabetic into a special character
|
8
|
-
text = text.squeeze(separator) # removes any consecutive duplicates of the special character
|
9
|
-
text = text.sub(Regexp.new("^#{ separator }+"), "") # remove leading special characters
|
10
|
-
text = text.sub(Regexp.new("#{ separator }+$"), "") # remove trailing special characters
|
11
|
-
text = text[0...max_length] if max_length # trim to length
|
12
|
-
|
13
|
-
text
|
3
|
+
Acts::Permalink::Conversion.convert(self.dup, max_length: max_length, separator: separator)
|
14
4
|
end
|
15
5
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_permalink
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin McPhillips
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -93,7 +93,10 @@ files:
|
|
93
93
|
- Rakefile
|
94
94
|
- lib/acts_as_permalink.rb
|
95
95
|
- lib/acts_as_permalink/version.rb
|
96
|
+
- lib/base.rb
|
97
|
+
- lib/concern.rb
|
96
98
|
- lib/config.rb
|
99
|
+
- lib/conversion.rb
|
97
100
|
- lib/string.rb
|
98
101
|
homepage: http://github.com/kmcphillips/acts_as_permalink
|
99
102
|
licenses: []
|