leifcr-mm-sluggable 0.2.7 → 0.2.8
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/Gemfile +1 -1
- data/README.md +6 -3
- data/lib/mm-sluggable.rb +58 -41
- data/lib/sluggable/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3214ed53cacd3ac3ff12234b600e1d0d7b76b70
|
4
|
+
data.tar.gz: 555ba0cfcbad7320ff2b91f8a7711c3f0dccbedc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f891fcd5e7c63be967b905c2b6273db21fd8d0765d65ff659c1f23238681cf406bb19543772242e27b0864457f5400c86430a7341f6b9c00056c9cd3e8501d3c
|
7
|
+
data.tar.gz: c3af64097217c705afb25a1ad0e8d79b1bbb5f7fe1d82db854837a2cb81f26c566e32328dd38f7655da1be538a868afe98a0bf718b73596575aa6c6800e80d55
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -45,18 +45,21 @@ Easiest is to add db/indexes.rb to your app, then add this to that file:
|
|
45
45
|
|
46
46
|
## Options
|
47
47
|
|
48
|
-
Available options
|
48
|
+
Available options:
|
49
49
|
|
50
50
|
* :scope - scope to a specific field (default - nil)
|
51
51
|
* :key - what the slug key is called (default - :slug) - NOTE, don't change this one
|
52
52
|
* :method - what method to call on the field to sluggify it (default - :parameterize)
|
53
|
-
* :callback - when to trigger the slugging (default - :
|
53
|
+
* :callback - when to trigger the slugging (default - :before_validation)
|
54
54
|
* :always_update - Always update the slug on update/save/create etc.
|
55
|
+
* :start - Which value the slugs should start with (default: 1)
|
56
|
+
* :max_length - The maxiumum length of the slug (default: 256)
|
57
|
+
* :disallowed\_bare\_slugs - Array of words that shouldn't be allowed as bare slugs. (default: ["new", "edit", "update", "create", "destroy"])
|
55
58
|
|
56
59
|
Eg.
|
57
60
|
|
58
61
|
```ruby
|
59
|
-
sluggable :title, scope: :account_id, key: :title_slug, method: :to_url, always_update: true
|
62
|
+
sluggable :title, scope: :account_id, key: :title_slug, method: :to_url, always_update: true, disallowed_bare_slugs: ["dragon", "unicorn", "dog"]
|
60
63
|
```
|
61
64
|
|
62
65
|
This will slug the title to the title_slug key, scoped to the account, will use String#to_url to slug it and won't add an index to the key
|
data/lib/mm-sluggable.rb
CHANGED
@@ -11,20 +11,24 @@ module MongoMapper
|
|
11
11
|
class_attribute :slug_options
|
12
12
|
|
13
13
|
self.slug_options = {
|
14
|
-
to_slug:
|
15
|
-
key:
|
16
|
-
method:
|
17
|
-
scope:
|
18
|
-
max_length:
|
19
|
-
start:
|
20
|
-
always_update:
|
21
|
-
callback:
|
22
|
-
callback_on:
|
14
|
+
to_slug: to_slug,
|
15
|
+
key: :slug,
|
16
|
+
method: :parameterize,
|
17
|
+
scope: nil,
|
18
|
+
max_length: 256,
|
19
|
+
start: 1,
|
20
|
+
always_update: true, # allow always updating slug...
|
21
|
+
callback: :before_validation,
|
22
|
+
callback_on: nil,
|
23
|
+
disallowed_bare_slugs: []
|
23
24
|
}.merge(options)
|
25
|
+
|
26
|
+
# Always dissallow new,edit,update,create,destroy as those are usually commands/routes
|
27
|
+
self.slug_options[:disallowed_bare_slugs].push(*["new", "edit", "update", "create", "destroy"])
|
24
28
|
key slug_options[:key], String
|
25
29
|
|
26
30
|
#before_validation :set_slug
|
27
|
-
self.send(slug_options[:callback], :set_slug, {:
|
31
|
+
self.send(slug_options[:callback], :set_slug, {on: slug_options[:callback_on]}) if slug_options[:callback] && slug_options[:callback_on]
|
28
32
|
self.send(slug_options[:callback], :set_slug) if slug_options[:callback] && slug_options[:callback_on].nil?
|
29
33
|
end
|
30
34
|
end
|
@@ -51,53 +55,66 @@ module MongoMapper
|
|
51
55
|
|
52
56
|
# previous_slug = self[:key]
|
53
57
|
|
54
|
-
|
58
|
+
raw_slug = to_slug.send(options[:method]).to_s[0...options[:max_length]]
|
59
|
+
if options[:disallowed_bare_slugs].include?(raw_slug)
|
60
|
+
the_slug = "#{raw_slug}-1"
|
61
|
+
else
|
62
|
+
the_slug = raw_slug
|
63
|
+
end
|
55
64
|
|
56
65
|
# no need to set, so return
|
57
66
|
return if (self.send(options[:key]) == the_slug)
|
58
67
|
# also do a regexp check,
|
59
68
|
# verify if the previous slug is "almost" the same as we want without digits/extras
|
60
69
|
return if (/(#{the_slug}-\d+)/.match(self.send(options[:key])) != nil)
|
61
|
-
|
62
70
|
conds = {}
|
63
71
|
conds[options[:key]] = the_slug
|
64
72
|
conds[options[:scope]] = self.send(options[:scope]) if options[:scope]
|
65
73
|
|
66
74
|
# first see if there is a equal slug
|
67
75
|
used_slugs = klass.where(conds).fields(options[:key])
|
68
|
-
|
69
|
-
|
70
|
-
# if we are updating, check if the current slug is same as the one we want
|
71
|
-
conds[options[:key]] = /(#{the_slug}-\d+)/
|
72
|
-
used_slugs = klass.where(conds).fields(options[:key])
|
73
|
-
used_slugs_array = Array.new
|
74
|
-
used_slugs.each do |used_slug|
|
75
|
-
used_slugs_array << used_slug.send(options[:key])[/(\d+)$/].to_i
|
76
|
-
end
|
77
|
-
used_slugs_array.sort!
|
76
|
+
# Then get the first available slug
|
77
|
+
the_slug = get_unused_slug(used_slugs, options, raw_slug, klass) if (used_slugs.count > 0)
|
78
78
|
|
79
|
-
|
80
|
-
|
79
|
+
self.send(:"#{options[:key]}=", the_slug)
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def get_unused_slug(used_slugs, options, raw_slug, klass)
|
85
|
+
last_digit = 0 # zero for last one...
|
86
|
+
# if we are updating, check if the current slug is same as the one we want
|
87
|
+
conds = {}
|
88
|
+
conds[options[:key]] = /(#{raw_slug}-\d+)/
|
89
|
+
conds[options[:scope]] = self.send(options[:scope]) if options[:scope]
|
90
|
+
|
91
|
+
used_slugs = klass.where(conds).fields(options[:key])
|
92
|
+
used_slugs_array = Array.new
|
93
|
+
used_slugs.each do |used_slug|
|
94
|
+
used_slugs_array << used_slug.send(options[:key])[/(\d+)$/].to_i
|
95
|
+
end
|
96
|
+
used_slugs_array.sort!
|
97
|
+
|
98
|
+
if used_slugs_array.length <= 0
|
99
|
+
next_digit = options[:start]
|
100
|
+
else
|
101
|
+
prev_num = used_slugs_array.shift
|
102
|
+
if used_slugs_array.length == 0
|
103
|
+
next_digit = prev_num + 1
|
81
104
|
else
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
used_slugs_array.each do |slug_num|
|
87
|
-
if ((slug_num - prev_num) > 1)
|
88
|
-
next_digit = prev_num + 1
|
89
|
-
break
|
90
|
-
end
|
91
|
-
next_digit = slug_num + 1
|
92
|
-
prev_num = slug_num
|
105
|
+
used_slugs_array.each do |slug_num|
|
106
|
+
if ((slug_num - prev_num) > 1)
|
107
|
+
next_digit = prev_num + 1
|
108
|
+
break
|
93
109
|
end
|
110
|
+
next_digit = slug_num + 1
|
111
|
+
prev_num = slug_num
|
94
112
|
end
|
95
113
|
end
|
96
|
-
the_slug = "#{raw_slug}-#{next_digit}"
|
97
114
|
end
|
98
|
-
|
99
|
-
self.send(:"#{options[:key]}=", the_slug)
|
115
|
+
"#{raw_slug}-#{next_digit}"
|
100
116
|
end
|
101
|
-
|
102
|
-
|
103
|
-
end
|
117
|
+
|
118
|
+
end #module Sluggable
|
119
|
+
end # module Plugins
|
120
|
+
end # module MongoMapper
|
data/lib/sluggable/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: leifcr-mm-sluggable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leif Ringstad
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongo_mapper
|