mongoid_slug 3.2.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a920281ade5b1dd639583fb26fe03d73889ee1f6
4
- data.tar.gz: b614389ac8cf8725170892ccbd91b385e2ff7e4e
3
+ metadata.gz: d7c5482b8203ac1d0077abb6d57c9b2395a8833c
4
+ data.tar.gz: 46495e284ce06a65efac3ff1105a8cc5f07042f5
5
5
  SHA512:
6
- metadata.gz: 1b58513044d6d147813315bfd44c1d8de70bb908cf54e3e4c1072e3090bce3bd8a0d6cd0333de181ed3d964eed674d5af0eb4e8c5263509bb799757159a39ff7
7
- data.tar.gz: d362fec6a047cc6adb0c843fa943c476528719d8febf78381fb97a830546d43b3540cd5035d01f9032444772a7660611af757407b689adb749491f1014294721
6
+ metadata.gz: dbb1ca989496522277f6c1b684df643a621e993b1a9f227de32331c5de15d65dcbfdc049588aadb2fbe1b3cb232f827012265cf4c336e53a128a965b6cf264f8
7
+ data.tar.gz: e8a8e0a3fce03e2505ee2f9e82d9dea61ddccfa23ffc02195ef2a67d8a8504524a54fd829fbf804e7879606e5ae610e95b1cb68e12190bc3a1a5e40f0222c4c3
data/README.md CHANGED
@@ -16,7 +16,7 @@ Installation
16
16
  Add to your Gemfile:
17
17
 
18
18
  ```ruby
19
- gem 'mongoid_slug'
19
+ gem 'mongoid-slug'
20
20
  ```
21
21
 
22
22
  Usage
@@ -297,6 +297,36 @@ unique = Mongoid::Slug::UniqueSlug.new(Book.new).find_unique(title)
297
297
  # return some representation of unique
298
298
  ```
299
299
 
300
+
301
+ Mongoid::Paranoia Support
302
+ -------------------------
303
+
304
+ The [Mongoid::Paranoia](http://github.com/simi/mongoid-paranoia) gem adds "soft-destroy" functionality to Mongoid documents.
305
+ Mongoid::Slug contains special handling for Mongoid::Paranoia:
306
+ - When destroying a paranoid document, the slug will be unset from the database.
307
+ - When restoring a paranoid document, the slug will be rebuilt. Note that the new slug may not match the old one.
308
+ - When resaving a destroyed paranoid document, the slug will remain unset in the database.
309
+ - For indexing purposes, sparse unique indexes are used. The sparse condition will ignore any destroyed paranoid documents, since their slug is not set in database.
310
+
311
+ ```ruby
312
+ class Entity
313
+ include Mongoid::Document
314
+ include Mongoid::Slug
315
+ include Mongoid::Paranoia
316
+ end
317
+ ```
318
+
319
+ The following variants of Mongoid Paranoia are officially supported:
320
+ * Mongoid 3 built-in Mongoid::Paranoia
321
+ * Mongoid 4 gem http://github.com/simi/mongoid-paranoia
322
+
323
+ Mongoid 4 gem "mongoid-paranoia" (http://github.com/haihappen/mongoid-paranoia)
324
+ is not officially supported but should also work.
325
+
326
+
327
+ References
328
+ ----------
329
+
300
330
  [1]: https://github.com/rsl/stringex/
301
331
  [2]: https://secure.travis-ci.org/hakanensari/mongoid-slug.png
302
332
  [3]: http://travis-ci.org/hakanensari/mongoid-slug
@@ -1,3 +1,11 @@
1
+ require 'mongoid'
2
+ require 'stringex'
3
+ require 'mongoid/slug/criteria'
4
+ require 'mongoid/slug/index'
5
+ require 'mongoid/slug/paranoia'
6
+ require 'mongoid/slug/unique_slug'
7
+ require 'mongoid/slug/slug_id_strategy'
8
+
1
9
  module Mongoid
2
10
  # Slugs your Mongoid model.
3
11
  module Slug
@@ -59,24 +67,9 @@ module Mongoid
59
67
  field :_slugs, type: Array, default: [], localize: options[:localize]
60
68
  alias_attribute :slugs, :_slugs
61
69
 
70
+ # Set index
62
71
  unless embedded?
63
- if slug_scope
64
- scope_key = (metadata = self.reflect_on_association(slug_scope)) ? metadata.key : slug_scope
65
- if options[:by_model_type] == true
66
- # Add _type to the index to fix polymorphism
67
- index({ _type: 1, scope_key => 1, _slugs: 1})
68
- else
69
- index({scope_key => 1, _slugs: 1}, {unique: true, sparse: true})
70
- end
71
-
72
- else
73
- # Add _type to the index to fix polymorphism
74
- if options[:by_model_type] == true
75
- index({_type: 1, _slugs: 1})
76
- else
77
- index({_slugs: 1}, {unique: true, sparse: true})
78
- end
79
- end
72
+ index(*Mongoid::Slug::Index.build_index(self.slug_scope_key, self.by_model_type))
80
73
  end
81
74
 
82
75
  #-- Why is it necessary to customize the slug builder?
@@ -93,12 +86,33 @@ module Mongoid
93
86
  else
94
87
  set_callback :save, :before, :build_slug, :if => :slug_should_be_rebuilt?
95
88
  end
89
+
90
+ # If paranoid document:
91
+ # - include shim to add callbacks for restore method
92
+ # - unset the slugs on destroy
93
+ # - recreate the slug on restore
94
+ # - force reset the slug when saving a destroyed paranoid document, to ensure it stays unset in the database
95
+ if is_paranoid_doc?
96
+ self.send(:include, Mongoid::Slug::Paranoia) unless self.respond_to?(:before_restore)
97
+ set_callback :destroy, :after, :unset_slug!
98
+ set_callback :restore, :before, :set_slug!
99
+ set_callback :save, :before, :reset_slug!, :if => :paranoid_deleted?
100
+ set_callback :save, :after, :clear_slug!, :if => :paranoid_deleted?
101
+ end
96
102
  end
97
103
 
98
104
  def look_like_slugs?(*args)
99
105
  with_default_scope.look_like_slugs?(*args)
100
106
  end
101
107
 
108
+ # Returns the scope key for indexing, considering associations
109
+ #
110
+ # @return [ Array<Document>, Document ] Whether the document is paranoid
111
+ def slug_scope_key
112
+ return nil unless self.slug_scope
113
+ self.reflect_on_association(self.slug_scope).try(:key) || self.slug_scope
114
+ end
115
+
102
116
  # Find documents by slugs.
103
117
  #
104
118
  # A document matches if any of its slugs match one of the supplied params.
@@ -124,6 +138,16 @@ module Mongoid
124
138
  scope_stack.last || Criteria.new(self) # Use Mongoid::Slug::Criteria for slugged documents.
125
139
  end
126
140
 
141
+ # Indicates whether or not the document includes Mongoid::Paranoia
142
+ #
143
+ # This can be replaced with .paranoid? method once the following PRs are merged:
144
+ # - https://github.com/simi/mongoid-paranoia/pull/19
145
+ # - https://github.com/haihappen/mongoid-paranoia/pull/3
146
+ #
147
+ # @return [ Array<Document>, Document ] Whether the document is paranoid
148
+ def is_paranoid_doc?
149
+ !!(defined?(::Mongoid::Paranoia) && self < ::Mongoid::Paranoia)
150
+ end
127
151
  end
128
152
 
129
153
  # Builds a new slug.
@@ -135,18 +159,18 @@ module Mongoid
135
159
  orig_locale = I18n.locale
136
160
  all_locales.each do |target_locale|
137
161
  I18n.locale = target_locale
138
- set_slug
162
+ apply_slug
139
163
  end
140
164
  ensure
141
165
  I18n.locale = orig_locale
142
166
  end
143
167
  else
144
- set_slug
168
+ apply_slug
145
169
  end
146
170
  true
147
171
  end
148
172
 
149
- def set_slug
173
+ def apply_slug
150
174
  _new_slug = find_unique_slug
151
175
 
152
176
  #skip slug generation and use Mongoid id
@@ -163,6 +187,35 @@ module Mongoid
163
187
  end
164
188
  end
165
189
 
190
+ # Builds slug then atomically sets it in the database.
191
+ # This is used when working with the Mongoid::Paranoia restore callback.
192
+ #
193
+ # This method is adapted to use the :set method variants from both
194
+ # Mongoid 3 (two args) and Mongoid 4 (hash arg)
195
+ def set_slug!
196
+ build_slug
197
+ self.method(:set).arity == 1 ? set({_slugs: self._slugs}) : set(:_slugs, self._slugs)
198
+ end
199
+
200
+ # Atomically unsets the slug field in the database. It is important to unset
201
+ # the field for the sparse index on slugs.
202
+ #
203
+ # This also resets the in-memory value of the slug field to its default (empty array)
204
+ def unset_slug!
205
+ unset(:_slugs)
206
+ clear_slug!
207
+ end
208
+
209
+ # Rolls back the slug value from the Mongoid changeset.
210
+ def reset_slug!
211
+ self.reset__slugs!
212
+ end
213
+
214
+ # Sets the slug to its default value.
215
+ def clear_slug!
216
+ self._slugs = []
217
+ end
218
+
166
219
  # Finds a unique slug, were specified string used to generate a slug.
167
220
  #
168
221
  # Returned slug will the same as the specified string when there are no
@@ -175,7 +228,15 @@ module Mongoid
175
228
 
176
229
  # @return [Boolean] Whether the slug requires to be rebuilt
177
230
  def slug_should_be_rebuilt?
178
- new_record? or _slugs_changed? or slugged_attributes_changed?
231
+ (new_record? or _slugs_changed? or slugged_attributes_changed?) and !paranoid_deleted?
232
+ end
233
+
234
+ # Indicates whether or not the document has been deleted in paranoid fashion
235
+ # Always returns false if the document is not paranoid
236
+ #
237
+ # @return [Boolean] Whether or not the document has been deleted in paranoid fashion
238
+ def paranoid_deleted?
239
+ !!(self.class.is_paranoid_doc? and self.deleted_at != nil)
179
240
  end
180
241
 
181
242
  def slugged_attributes_changed?
@@ -270,4 +331,3 @@ module Mongoid
270
331
  end
271
332
  end
272
333
  end
273
-
@@ -0,0 +1,27 @@
1
+ module Mongoid
2
+ module Slug
3
+ module Index
4
+
5
+ # @param [ String or Symbol ] scope_key The optional scope key for the index
6
+ # @param [ Boolean ] by_model_type Whether or not
7
+ #
8
+ # @return [ Array(Hash, Hash) ] the indexable fields and index options.
9
+ def self.build_index(scope_key = nil, by_model_type = false)
10
+ fields = {_slugs: 1}
11
+ options = {}
12
+
13
+ if scope_key
14
+ fields.merge!({scope_key => 1})
15
+ end
16
+
17
+ if by_model_type
18
+ fields.merge!({_type: 1})
19
+ else
20
+ options.merge!({unique: true, sparse: true})
21
+ end
22
+
23
+ return [fields, options]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module Mongoid
2
+ module Slug
3
+
4
+ # Lightweight compatibility shim which adds the :restore callback to
5
+ # older versions of Mongoid::Paranoia
6
+ module Paranoia
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+
11
+ define_model_callbacks :restore
12
+
13
+ def restore_with_callbacks
14
+ run_callbacks(:restore) do
15
+ restore_without_callbacks
16
+ end
17
+ end
18
+ alias_method_chain :restore, :callbacks
19
+ end
20
+ end
21
+ end
22
+ end
@@ -4,7 +4,7 @@ require 'forwardable'
4
4
  module Mongoid
5
5
  module Slug
6
6
  class UniqueSlug
7
-
7
+ MUTEX_FOR_SLUG = Mutex.new
8
8
  class SlugState
9
9
  attr_reader :last_entered_slug, :existing_slugs, :existing_history_slugs, :sorted_existing
10
10
 
@@ -76,45 +76,47 @@ module Mongoid
76
76
  end
77
77
 
78
78
  def find_unique attempt = nil
79
- @_slug = if attempt
80
- attempt.to_url
81
- else
82
- url_builder.call(model)
83
- end
84
- # Regular expression that matches slug, slug-1, ... slug-n
85
- # If slug_name field was indexed, MongoDB will utilize that
86
- # index to match /^.../ pattern.
87
- pattern = /^#{Regexp.escape(@_slug)}(?:-(\d+))?$/
88
-
89
- where_hash = {}
90
- where_hash[:_slugs.all] = [pattern]
91
- where_hash[:_id.ne] = model._id
92
-
93
- if (scope = slug_scope) && reflect_on_association(scope).nil?
94
- # scope is not an association, so it's scoped to a local field
95
- # (e.g. an association id in a denormalized db design)
96
- where_hash[scope] = model.try(:read_attribute, scope)
97
- end
98
-
99
- if by_model_type == true
100
- where_hash[:_type] = model.try(:read_attribute, :_type)
101
- end
102
-
103
- @state = SlugState.new @_slug, uniqueness_scope.unscoped.where(where_hash), pattern
104
-
105
- # do not allow a slug that can be interpreted as the current document id
106
- @state.include_slug unless model.class.look_like_slugs?([@_slug])
107
-
108
- # make sure that the slug is not equal to a reserved word
109
- @state.include_slug if reserved_words.any? { |word| word === @_slug }
110
-
111
- # only look for a new unique slug if the existing slugs contains the current slug
112
- # - e.g if the slug 'foo-2' is taken, but 'foo' is available, the user can use 'foo'.
113
- if @state.slug_included?
114
- highest = @state.highest_existing_counter
115
- @_slug += "-#{highest.succ}"
79
+ MUTEX_FOR_SLUG.synchronize do
80
+ @_slug = if attempt
81
+ attempt.to_url
82
+ else
83
+ url_builder.call(model)
84
+ end
85
+ # Regular expression that matches slug, slug-1, ... slug-n
86
+ # If slug_name field was indexed, MongoDB will utilize that
87
+ # index to match /^.../ pattern.
88
+ pattern = /^#{Regexp.escape(@_slug)}(?:-(\d+))?$/
89
+
90
+ where_hash = {}
91
+ where_hash[:_slugs.all] = [pattern]
92
+ where_hash[:_id.ne] = model._id
93
+
94
+ if (scope = slug_scope) && reflect_on_association(scope).nil?
95
+ # scope is not an association, so it's scoped to a local field
96
+ # (e.g. an association id in a denormalized db design)
97
+ where_hash[scope] = model.try(:read_attribute, scope)
98
+ end
99
+
100
+ if by_model_type == true
101
+ where_hash[:_type] = model.try(:read_attribute, :_type)
102
+ end
103
+
104
+ @state = SlugState.new @_slug, uniqueness_scope.unscoped.where(where_hash), pattern
105
+
106
+ # do not allow a slug that can be interpreted as the current document id
107
+ @state.include_slug unless model.class.look_like_slugs?([@_slug])
108
+
109
+ # make sure that the slug is not equal to a reserved word
110
+ @state.include_slug if reserved_words.any? { |word| word === @_slug }
111
+
112
+ # only look for a new unique slug if the existing slugs contains the current slug
113
+ # - e.g if the slug 'foo-2' is taken, but 'foo' is available, the user can use 'foo'.
114
+ if @state.slug_included?
115
+ highest = @state.highest_existing_counter
116
+ @_slug += "-#{highest.succ}"
117
+ end
118
+ @_slug
116
119
  end
117
- @_slug
118
120
  end
119
121
 
120
122
  def uniqueness_scope
@@ -1,5 +1,5 @@
1
1
  module Mongoid #:nodoc:
2
2
  module Slug
3
- VERSION = '3.2.1'
3
+ VERSION = '4.0.0'
4
4
  end
5
5
  end
@@ -1,6 +1,2 @@
1
- require 'mongoid'
2
- require 'stringex'
1
+ # To be removed
3
2
  require 'mongoid/slug'
4
- require 'mongoid/slug/criteria'
5
- require 'mongoid/slug/unique_slug'
6
- require 'mongoid/slug/slug_id_strategy'
@@ -5,5 +5,5 @@ class Page
5
5
  field :content
6
6
  field :order, :type => Integer
7
7
  slug :title
8
- default_scope asc(:order)
8
+ default_scope ->{ asc(:order) }
9
9
  end
@@ -5,5 +5,5 @@ class PageLocalize
5
5
  field :content
6
6
  field :order, :type => Integer
7
7
  slug :title
8
- default_scope asc(:order)
8
+ default_scope ->{ asc(:order) }
9
9
  end
@@ -5,5 +5,5 @@ class PageSlugLocalized
5
5
  field :content
6
6
  field :order, :type => Integer
7
7
  slug :title, localize: true
8
- default_scope asc(:order)
8
+ default_scope ->{ asc(:order) }
9
9
  end
@@ -5,5 +5,5 @@ class PageSlugLocalizedHistory
5
5
  field :content
6
6
  field :order, :type => Integer
7
7
  slug :title, localize: true, history: true
8
- default_scope asc(:order)
8
+ default_scope ->{ asc(:order) }
9
9
  end
@@ -0,0 +1,8 @@
1
+ class ParanoidPermanent
2
+ include Mongoid::Document
3
+ include Mongoid::Paranoia
4
+ include Mongoid::Slug
5
+
6
+ field :title
7
+ slug :title, permanent: true
8
+ end
@@ -0,0 +1,34 @@
1
+ #encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Mongoid::Slug::Index do
5
+
6
+ let(:scope_key) { nil }
7
+ let(:by_model_type) { false }
8
+ subject { Mongoid::Slug::Index.build_index(scope_key, by_model_type) }
9
+
10
+ context "when scope_key is set" do
11
+ let(:scope_key) { :foo }
12
+
13
+ context "when by_model_type is true" do
14
+ let(:by_model_type) { true }
15
+ it { should eq [{:_slugs=>1, :foo=>1, :_type=>1}, {}] }
16
+ end
17
+
18
+ context "when by_model_type is false" do
19
+ it { should eq [{:_slugs=>1, :foo=>1}, {:unique=>true, :sparse=>true}] }
20
+ end
21
+ end
22
+
23
+ context "when scope_key is not set" do
24
+
25
+ context "when by_model_type is true" do
26
+ let(:by_model_type) { true }
27
+ it { should eq [{:_slugs=>1, :_type=>1}, {}] }
28
+ end
29
+
30
+ context "when by_model_type is false" do
31
+ it { should eq [{:_slugs=>1}, {:unique=>true, :sparse=>true}] }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,169 @@
1
+ #encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe "Mongoid::Paranoia with Mongoid::Slug" do
5
+
6
+ let(:paranoid_doc) { ParanoidDocument.create!(:title => "slug") }
7
+ let(:paranoid_doc_2) { ParanoidDocument.create!(:title => "slug") }
8
+ let(:paranoid_perm) { ParanoidPermanent.create!(:title => "slug") }
9
+ let(:paranoid_perm_2) { ParanoidPermanent.create!(:title => "slug") }
10
+ let(:non_paranoid_doc){ Article.create!(:title => "slug") }
11
+ subject{ paranoid_doc }
12
+
13
+ describe ".paranoid?" do
14
+
15
+ context "when Mongoid::Paranoia is included" do
16
+ subject { paranoid_doc.class }
17
+ its(:is_paranoid_doc?){ should be_truthy }
18
+ end
19
+
20
+ context "when Mongoid::Paranoia not included" do
21
+ subject { non_paranoid_doc.class }
22
+ its(:is_paranoid_doc?){ should be_falsey }
23
+ end
24
+ end
25
+
26
+ describe "#paranoid_deleted?" do
27
+
28
+ context "when Mongoid::Paranoia is included" do
29
+
30
+ context "when not destroyed" do
31
+ its(:paranoid_deleted?){ should be_falsey }
32
+ end
33
+
34
+ context "when destroyed" do
35
+ before { subject.destroy }
36
+ its(:paranoid_deleted?){ should be_truthy }
37
+ end
38
+ end
39
+
40
+ context "when Mongoid::Paranoia not included" do
41
+ subject { non_paranoid_doc }
42
+ its(:paranoid_deleted?){ should be_falsey }
43
+ end
44
+ end
45
+
46
+ describe "restore callbacks" do
47
+
48
+ context "when Mongoid::Paranoia is included" do
49
+ subject { paranoid_doc.class }
50
+ it { should respond_to(:before_restore) }
51
+ it { should respond_to(:after_restore) }
52
+ end
53
+
54
+ context "when Mongoid::Paranoia not included" do
55
+ it { should_not respond_to(:before_restore) }
56
+ it { should_not respond_to(:after_restore) }
57
+ end
58
+ end
59
+
60
+ describe "index" do
61
+ before { ParanoidDocument.create_indexes }
62
+ after { ParanoidDocument.remove_indexes }
63
+ subject { ParanoidDocument }
64
+
65
+ it_should_behave_like "has an index", { _slugs: 1 }, { unique: true, sparse: true }
66
+ end
67
+
68
+ shared_examples_for "paranoid slugs" do
69
+
70
+ context "querying" do
71
+
72
+ it "returns paranoid_doc for correct slug" do
73
+ subject.class.find(subject.slug).should eq(subject)
74
+ end
75
+ end
76
+
77
+ context "delete (callbacks not fired)" do
78
+
79
+ before { subject.delete }
80
+
81
+ it "retains slug value" do
82
+ subject.slug.should eq "slug"
83
+ subject.class.unscoped.find("slug").should eq subject
84
+ end
85
+ end
86
+
87
+ context "destroy" do
88
+
89
+ before { subject.destroy }
90
+
91
+ it "unsets slug value when destroyed" do
92
+ subject._slugs.should eq []
93
+ subject.slug.should be_nil
94
+ end
95
+
96
+ it "persists the removed slug" do
97
+ subject.reload._slugs.should eq []
98
+ subject.reload.slug.should be_nil
99
+ end
100
+
101
+ it "persists the removed slug in the database" do
102
+ subject.class.unscoped.exists(_slugs: false).first.should eq subject
103
+ expect{subject.class.unscoped.find("slug")}.to raise_error(Mongoid::Errors::DocumentNotFound)
104
+ end
105
+
106
+ context "when saving the doc again" do
107
+
108
+ before { subject.save }
109
+
110
+ it "should have the default slug value" do
111
+ subject._slugs.should eq []
112
+ subject.slug.should be_nil
113
+ end
114
+
115
+ it "the slug remains unset in the database" do
116
+ subject.class.unscoped.exists(_slugs: false).first.should eq subject
117
+ expect{subject.class.unscoped.find("slug")}.to raise_error(Mongoid::Errors::DocumentNotFound)
118
+ end
119
+ end
120
+ end
121
+
122
+ context "restore" do
123
+
124
+ before do
125
+ subject.destroy
126
+ subject.restore
127
+ end
128
+
129
+ it "resets slug value when restored" do
130
+ subject.slug.should eq "slug"
131
+ subject.reload.slug.should eq "slug"
132
+ end
133
+ end
134
+
135
+ context "multiple documents" do
136
+
137
+ it "new documents should be able to use the slug of destroyed documents" do
138
+ subject.slug.should eq "slug"
139
+ subject.destroy
140
+ subject.reload.slug.should be_nil
141
+ other_doc.slug.should eq "slug"
142
+ subject.restore
143
+ subject.slug.should eq "slug-1"
144
+ subject.reload.slug.should eq "slug-1"
145
+ end
146
+
147
+ it "should allow multiple documents to be destroyed without index conflict" do
148
+ subject.slug.should eq "slug"
149
+ subject.destroy
150
+ subject.reload.slug.should be_nil
151
+ other_doc.slug.should eq "slug"
152
+ other_doc.destroy
153
+ other_doc.reload.slug.should be_nil
154
+ end
155
+ end
156
+ end
157
+
158
+ context "non-permanent slug" do
159
+ subject { paranoid_doc }
160
+ let(:other_doc) { paranoid_doc_2 }
161
+ it_behaves_like "paranoid slugs"
162
+ end
163
+
164
+ context "permanent slug" do
165
+ subject { paranoid_perm }
166
+ let(:other_doc) { paranoid_perm_2 }
167
+ it_behaves_like "paranoid slugs"
168
+ end
169
+ end
@@ -523,7 +523,7 @@ module Mongoid
523
523
 
524
524
  context "when slug is not scoped by a reference association" do
525
525
  subject { Book }
526
- it_should_behave_like "has an index", { _slugs: 1 }, { unique: true }
526
+ it_should_behave_like "has an index", { _slugs: 1 }, { unique: true, sparse: true }
527
527
  end
528
528
 
529
529
  context "when slug is scoped by a reference association" do
@@ -534,7 +534,7 @@ module Mongoid
534
534
  context "for subclass scope" do
535
535
  context "when slug is not scoped by a reference association" do
536
536
  subject { BookPolymorphic }
537
- it_should_behave_like "has an index", { _type: 1, _slugs: 1 }, { unique: nil }
537
+ it_should_behave_like "has an index", { _type: 1, _slugs: 1 }, { unique: nil, sparse: nil }
538
538
  end
539
539
 
540
540
  context "when slug is scoped by a reference association" do
@@ -672,12 +672,12 @@ module Mongoid
672
672
  let(:book) { Book.first }
673
673
 
674
674
  it "is initially unchanged" do
675
- book._slugs_changed?.should be_false
675
+ book._slugs_changed?.should be_falsey
676
676
  end
677
677
 
678
678
  it "tracks changes" do
679
679
  book.slugs = ["Anti Oedipus"]
680
- book._slugs_changed?.should be_true
680
+ book._slugs_changed?.should be_truthy
681
681
  end
682
682
  end
683
683
 
@@ -1018,25 +1018,5 @@ module Mongoid
1018
1018
  end
1019
1019
 
1020
1020
  end
1021
-
1022
- context "Mongoid paranoia with mongoid slug model" do
1023
-
1024
- let(:paranoid_doc) {ParanoidDocument.create!(:title => "slug")}
1025
-
1026
- it "returns paranoid_doc for correct slug" do
1027
- ParanoidDocument.find(paranoid_doc.slug).should eq(paranoid_doc)
1028
- end
1029
-
1030
- it "raises for deleted slug" do
1031
- paranoid_doc.delete
1032
- expect{ParanoidDocument.find(paranoid_doc.slug)}.to raise_error(Mongoid::Errors::DocumentNotFound)
1033
- end
1034
-
1035
- it "returns paranoid_doc for correct restored slug" do
1036
- paranoid_doc.delete
1037
- ParanoidDocument.deleted.first.restore
1038
- ParanoidDocument.find(paranoid_doc.slug).should eq(paranoid_doc)
1039
- end
1040
- end
1041
1021
  end
1042
1022
  end
@@ -1,13 +1,19 @@
1
+ require 'bundler/setup'
2
+
1
3
  begin
2
4
  require 'pry'
3
5
  rescue LoadError
4
6
  end
5
7
  require 'rspec'
6
8
  require 'uuid'
7
- require "awesome_print"
8
-
9
- require File.expand_path '../../lib/mongoid_slug', __FILE__
9
+ require 'awesome_print'
10
+ require 'active_support'
11
+ require 'active_support/deprecation'
12
+ require 'mongoid'
10
13
  require 'mongoid/paranoia'
14
+ require 'rspec/its'
15
+
16
+ require File.expand_path '../../lib/mongoid/slug', __FILE__
11
17
 
12
18
  module Mongoid::Slug::UuidIdStrategy
13
19
  def self.call id
@@ -32,7 +38,7 @@ I18n.available_locales = [ :en, :nl ]
32
38
  RSpec.configure do |c|
33
39
  c.before(:each) do
34
40
  Mongoid.purge!
35
- Mongoid::IdentityMap.clear
41
+ Mongoid::IdentityMap.clear if defined?(Mongoid::IdentityMap)
36
42
  end
37
43
 
38
44
  c.after(:suite) do
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_slug
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Saebjoernsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-07 00:00:00.000000000 Z
11
+ date: 2014-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mongoid
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.0'
27
27
  - !ruby/object:Gem::Dependency
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-its
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: awesome_print
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -133,6 +147,8 @@ files:
133
147
  - README.md
134
148
  - lib/mongoid/slug.rb
135
149
  - lib/mongoid/slug/criteria.rb
150
+ - lib/mongoid/slug/index.rb
151
+ - lib/mongoid/slug/paranoia.rb
136
152
  - lib/mongoid/slug/slug_id_strategy.rb
137
153
  - lib/mongoid/slug/unique_slug.rb
138
154
  - lib/mongoid/slug/version.rb
@@ -155,6 +171,7 @@ files:
155
171
  - spec/models/page_slug_localized_custom.rb
156
172
  - spec/models/page_slug_localized_history.rb
157
173
  - spec/models/paranoid_document.rb
174
+ - spec/models/paranoid_permanent.rb
158
175
  - spec/models/partner.rb
159
176
  - spec/models/person.rb
160
177
  - spec/models/relationship.rb
@@ -162,6 +179,8 @@ files:
162
179
  - spec/models/subject.rb
163
180
  - spec/models/without_slug.rb
164
181
  - spec/mongoid/criteria_spec.rb
182
+ - spec/mongoid/index_spec.rb
183
+ - spec/mongoid/paranoia_spec.rb
165
184
  - spec/mongoid/slug_spec.rb
166
185
  - spec/mongoid/slug_spec.rb.b00
167
186
  - spec/shared/indexes.rb
@@ -170,7 +189,9 @@ homepage: https://github.com/digitalplaywright/mongoid-slug
170
189
  licenses:
171
190
  - MIT
172
191
  metadata: {}
173
- post_install_message:
192
+ post_install_message: "[NOTICE]: Deprecated gem name. The name of this gem will be
193
+ changing from 'mongoid_slug' to 'mongoid-slug' (notice the hyphen). To ensure you
194
+ are using the correct version of this gem, please use 'mongoid-slug'."
174
195
  rdoc_options: []
175
196
  require_paths:
176
197
  - lib
@@ -209,6 +230,7 @@ test_files:
209
230
  - spec/models/page_slug_localized_custom.rb
210
231
  - spec/models/page_slug_localized_history.rb
211
232
  - spec/models/paranoid_document.rb
233
+ - spec/models/paranoid_permanent.rb
212
234
  - spec/models/partner.rb
213
235
  - spec/models/person.rb
214
236
  - spec/models/relationship.rb
@@ -216,7 +238,10 @@ test_files:
216
238
  - spec/models/subject.rb
217
239
  - spec/models/without_slug.rb
218
240
  - spec/mongoid/criteria_spec.rb
241
+ - spec/mongoid/index_spec.rb
242
+ - spec/mongoid/paranoia_spec.rb
219
243
  - spec/mongoid/slug_spec.rb
220
244
  - spec/mongoid/slug_spec.rb.b00
221
245
  - spec/shared/indexes.rb
222
246
  - spec/spec_helper.rb
247
+ has_rdoc: