leifcr-mm-sluggable 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|