mongoid-slug 6.0.1 → 7.0.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +34 -3
  3. data/lib/mongoid/slug/criteria.rb +10 -6
  4. data/lib/mongoid/slug/index_builder.rb +2 -0
  5. data/lib/mongoid/slug/railtie.rb +2 -0
  6. data/lib/mongoid/slug/slug_id_strategy.rb +2 -0
  7. data/lib/mongoid/slug/unique_slug.rb +8 -9
  8. data/lib/mongoid/slug/version.rb +4 -2
  9. data/lib/mongoid/slug.rb +15 -10
  10. data/lib/mongoid_slug.rb +2 -0
  11. data/lib/tasks/mongoid_slug.rake +3 -1
  12. metadata +9 -168
  13. data/spec/models/alias.rb +0 -6
  14. data/spec/models/article.rb +0 -9
  15. data/spec/models/artist.rb +0 -8
  16. data/spec/models/artwork.rb +0 -10
  17. data/spec/models/author.rb +0 -15
  18. data/spec/models/author_polymorphic.rb +0 -15
  19. data/spec/models/book.rb +0 -12
  20. data/spec/models/book_polymorphic.rb +0 -12
  21. data/spec/models/caption.rb +0 -17
  22. data/spec/models/entity.rb +0 -11
  23. data/spec/models/friend.rb +0 -7
  24. data/spec/models/incorrect_slug_persistence.rb +0 -9
  25. data/spec/models/integer_id.rb +0 -9
  26. data/spec/models/magazine.rb +0 -7
  27. data/spec/models/page.rb +0 -9
  28. data/spec/models/page_localize.rb +0 -9
  29. data/spec/models/page_slug_localized.rb +0 -9
  30. data/spec/models/page_slug_localized_custom.rb +0 -10
  31. data/spec/models/page_slug_localized_history.rb +0 -9
  32. data/spec/models/partner.rb +0 -7
  33. data/spec/models/person.rb +0 -12
  34. data/spec/models/relationship.rb +0 -8
  35. data/spec/models/string_id.rb +0 -9
  36. data/spec/models/subject.rb +0 -7
  37. data/spec/models/without_slug.rb +0 -5
  38. data/spec/mongoid/criteria_spec.rb +0 -207
  39. data/spec/mongoid/index_builder_spec.rb +0 -105
  40. data/spec/mongoid/slug_spec.rb +0 -1175
  41. data/spec/shared/indexes.rb +0 -41
  42. data/spec/spec_helper.rb +0 -61
  43. data/spec/tasks/mongoid_slug_rake_spec.rb +0 -73
@@ -1,11 +0,0 @@
1
- class Entity
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
-
5
- field :_id, type: String, slug_id_strategy: UuidIdStrategy
6
-
7
- field :name
8
- field :user_edited_variation
9
-
10
- slug :user_edited_variation, history: true
11
- end
@@ -1,7 +0,0 @@
1
- class Friend
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :name
5
- field :slug_history, type: Array
6
- slug :name, reserve: ['foo', 'bar', /^[a-z]{2}$/i], history: true
7
- end
@@ -1,9 +0,0 @@
1
- class IncorrectSlugPersistence
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
-
5
- field :name
6
- slug :name, history: true
7
-
8
- validates_length_of :name, minimum: 4, maximum: 5, allow_blank: true
9
- end
@@ -1,9 +0,0 @@
1
- class IntegerId
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
-
5
- field :_id, type: Integer
6
- field :name, type: String
7
-
8
- slug :name, history: true
9
- end
@@ -1,7 +0,0 @@
1
- class Magazine
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :title
5
- field :publisher_id
6
- slug :title, scope: :publisher_id
7
- end
data/spec/models/page.rb DELETED
@@ -1,9 +0,0 @@
1
- class Page
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :title
5
- field :content
6
- field :order, type: Integer
7
- slug :title
8
- default_scope -> { asc(:order) }
9
- end
@@ -1,9 +0,0 @@
1
- class PageLocalize
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :title, localize: true
5
- field :content
6
- field :order, type: Integer
7
- slug :title
8
- default_scope -> { asc(:order) }
9
- end
@@ -1,9 +0,0 @@
1
- class PageSlugLocalized
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :title, localize: true
5
- field :content
6
- field :order, type: Integer
7
- slug :title, localize: true
8
- default_scope -> { asc(:order) }
9
- end
@@ -1,10 +0,0 @@
1
- class PageSlugLocalizedCustom
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
-
5
- attr_accessor :title
6
-
7
- slug :title, localize: true do |obj|
8
- obj.title.to_url
9
- end
10
- end
@@ -1,9 +0,0 @@
1
- class PageSlugLocalizedHistory
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :title, localize: true
5
- field :content
6
- field :order, type: Integer
7
- slug :title, localize: true, history: true
8
- default_scope -> { asc(:order) }
9
- end
@@ -1,7 +0,0 @@
1
- class Partner
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :name
5
- slug :name
6
- embedded_in :relationship
7
- end
@@ -1,12 +0,0 @@
1
- class Person
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :name
5
- slug :name, permanent: true, scope: :author
6
- embeds_many :relationships
7
- if Mongoid::Compatibility::Version.mongoid6_or_newer?
8
- belongs_to :author, inverse_of: :characters, required: false
9
- else
10
- belongs_to :author, inverse_of: :characters
11
- end
12
- end
@@ -1,8 +0,0 @@
1
- class Relationship
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :name
5
- slug :name
6
- embeds_many :partners
7
- embedded_in :person
8
- end
@@ -1,9 +0,0 @@
1
- class StringId
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
-
5
- field :_id, type: String
6
- field :name, type: String
7
-
8
- slug :name, history: true
9
- end
@@ -1,7 +0,0 @@
1
- class Subject
2
- include Mongoid::Document
3
- include Mongoid::Slug
4
- field :name
5
- slug :name, scope: :book, history: true
6
- embedded_in :book
7
- end
@@ -1,5 +0,0 @@
1
- class WithoutSlug
2
- include Mongoid::Document
3
-
4
- field :_id, type: Integer
5
- end
@@ -1,207 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Mongoid::Slug::Criteria do
4
- describe '.find' do
5
- let!(:book) { Book.create(title: 'A Working Title').tap { |d| d.update_attribute(:title, 'A Thousand Plateaus') } }
6
- let!(:book2) { Book.create(title: 'Difference and Repetition') }
7
- let!(:friend) { Friend.create(name: 'Jim Bob') }
8
- let!(:friend2) { Friend.create(name: friend.id.to_s) }
9
- let!(:integer_id) { IntegerId.new(name: 'I have integer ids').tap { |d| d.id = 123; d.save! } }
10
- let!(:integer_id2) { IntegerId.new(name: integer_id.id.to_s).tap { |d| d.id = 456; d.save! } }
11
- let!(:string_id) { StringId.new(name: 'I have string ids').tap { |d| d.id = 'abc'; d.save! } }
12
- let!(:string_id2) { StringId.new(name: string_id.id.to_s).tap { |d| d.id = 'def'; d.save! } }
13
- let!(:subject) { Subject.create(name: 'A Subject', book: book) }
14
- let!(:subject2) { Subject.create(name: 'A Subject', book: book2) }
15
- let!(:without_slug) { WithoutSlug.new.tap { |d| d.id = 456; d.save! } }
16
-
17
- context 'when the model does not use mongoid slugs' do
18
- it "should not use mongoid slug's custom find methods" do
19
- expect_any_instance_of(Mongoid::Slug::Criteria).not_to receive(:find)
20
- expect(WithoutSlug.find(without_slug.id.to_s)).to eq(without_slug)
21
- end
22
- end
23
-
24
- context 'using slugs' do
25
- context '(single)' do
26
- context 'and a document is found' do
27
- it 'returns the document as an object' do
28
- expect(Book.find(book.slugs.first)).to eq(book)
29
- end
30
- end
31
-
32
- context 'but no document is found' do
33
- it 'raises a Mongoid::Errors::DocumentNotFound error' do
34
- expect do
35
- Book.find('Anti Oedipus')
36
- end.to raise_error(Mongoid::Errors::DocumentNotFound)
37
- end
38
- end
39
- end
40
-
41
- context '(multiple)' do
42
- context 'and all documents are found' do
43
- it 'returns the documents as an array without duplication' do
44
- expect(Book.find(book.slugs + book2.slugs)).to match_array([book, book2])
45
- end
46
- end
47
-
48
- context 'but not all documents are found' do
49
- it 'raises a Mongoid::Errors::DocumentNotFound error' do
50
- expect do
51
- Book.find(book.slugs + ['something-nonexistent'])
52
- end.to raise_error(Mongoid::Errors::DocumentNotFound)
53
- end
54
- end
55
- end
56
-
57
- context 'when no documents match' do
58
- it 'raises a Mongoid::Errors::DocumentNotFound error' do
59
- expect do
60
- Book.find('Anti Oedipus')
61
- end.to raise_error(Mongoid::Errors::DocumentNotFound)
62
- end
63
- end
64
-
65
- context 'when ids are BSON::ObjectIds and the supplied argument looks like a BSON::ObjectId' do
66
- it 'it should find based on ids not slugs' do # i.e. it should type cast the argument
67
- expect(Friend.find(friend.id.to_s)).to eq(friend)
68
- end
69
- end
70
-
71
- context 'when ids are Strings' do
72
- it 'it should find based on ids not slugs' do # i.e. string ids should take precedence over string slugs
73
- expect(StringId.find(string_id.id.to_s)).to eq(string_id)
74
- end
75
- end
76
-
77
- context 'when ids are Integers and the supplied arguments looks like an Integer' do
78
- it 'it should find based on slugs not ids' do # i.e. it should not type cast the argument
79
- expect(IntegerId.find(integer_id.id.to_s)).to eq(integer_id2)
80
- end
81
- end
82
-
83
- context 'models that does not use slugs, should find using the original find' do
84
- it 'it should find based on ids' do # i.e. it should not type cast the argument
85
- expect(WithoutSlug.find(without_slug.id.to_s)).to eq(without_slug)
86
- end
87
- end
88
-
89
- context 'when scoped' do
90
- context 'and a document is found' do
91
- it 'returns the document as an object' do
92
- expect(book.subjects.find(subject.slugs.first)).to eq(subject)
93
- expect(book2.subjects.find(subject.slugs.first)).to eq(subject2)
94
- end
95
- end
96
-
97
- context 'but no document is found' do
98
- it 'raises a Mongoid::Errors::DocumentNotFound error' do
99
- expect do
100
- book.subjects.find('Another Subject')
101
- end.to raise_error(Mongoid::Errors::DocumentNotFound)
102
- end
103
- end
104
- end
105
- end
106
-
107
- context 'using ids' do
108
- it 'raises a Mongoid::Errors::DocumentNotFound error if no document is found' do
109
- expect do
110
- Book.find(friend.id)
111
- end.to raise_error(Mongoid::Errors::DocumentNotFound)
112
- end
113
-
114
- context 'given a single document' do
115
- it 'returns the document' do
116
- expect(Friend.find(friend.id)).to eq(friend)
117
- end
118
- end
119
-
120
- context 'given multiple documents' do
121
- it 'returns the documents' do
122
- expect(Book.find([book.id, book2.id])).to match_array([book, book2])
123
- end
124
- end
125
- end
126
- end
127
-
128
- describe '.find_by_slug!' do
129
- let!(:book) { Book.create(title: 'A Working Title').tap { |d| d.update_attribute(:title, 'A Thousand Plateaus') } }
130
- let!(:book2) { Book.create(title: 'Difference and Repetition') }
131
- let!(:friend) { Friend.create(name: 'Jim Bob') }
132
- let!(:friend2) { Friend.create(name: friend.id.to_s) }
133
- let!(:integer_id) { IntegerId.new(name: 'I have integer ids').tap { |d| d.id = 123; d.save! } }
134
- let!(:integer_id2) { IntegerId.new(name: integer_id.id.to_s).tap { |d| d.id = 456; d.save! } }
135
- let!(:string_id) { StringId.new(name: 'I have string ids').tap { |d| d.id = 'abc'; d.save! } }
136
- let!(:string_id2) { StringId.new(name: string_id.id.to_s).tap { |d| d.id = 'def'; d.save! } }
137
- let!(:subject) { Subject.create(name: 'A Subject', book: book) }
138
- let!(:subject2) { Subject.create(name: 'A Subject', book: book2) }
139
-
140
- context '(single)' do
141
- context 'and a document is found' do
142
- it 'returns the document as an object' do
143
- expect(Book.find_by_slug!(book.slugs.first)).to eq(book)
144
- end
145
- end
146
-
147
- context 'but no document is found' do
148
- it 'raises a Mongoid::Errors::DocumentNotFound error' do
149
- expect do
150
- Book.find_by_slug!('Anti Oedipus')
151
- end.to raise_error(Mongoid::Errors::DocumentNotFound)
152
- end
153
- end
154
- end
155
-
156
- context '(multiple)' do
157
- context 'and all documents are found' do
158
- it 'returns the documents as an array without duplication' do
159
- expect(Book.find_by_slug!(book.slugs + book2.slugs)).to match_array([book, book2])
160
- end
161
- end
162
-
163
- context 'but not all documents are found' do
164
- it 'raises a Mongoid::Errors::DocumentNotFound error' do
165
- expect do
166
- Book.find_by_slug!(book.slugs + ['something-nonexistent'])
167
- end.to raise_error(Mongoid::Errors::DocumentNotFound)
168
- end
169
- end
170
- end
171
-
172
- context 'when scoped' do
173
- context 'and a document is found' do
174
- it 'returns the document as an object' do
175
- expect(book.subjects.find_by_slug!(subject.slugs.first)).to eq(subject)
176
- expect(book2.subjects.find_by_slug!(subject.slugs.first)).to eq(subject2)
177
- end
178
- end
179
-
180
- context 'but no document is found' do
181
- it 'raises a Mongoid::Errors::DocumentNotFound error' do
182
- expect do
183
- book.subjects.find_by_slug!('Another Subject')
184
- end.to raise_error(Mongoid::Errors::DocumentNotFound)
185
- end
186
- end
187
- end
188
- end
189
-
190
- describe '.where' do
191
- let!(:artist1) { Artist.create!(name: 'Leonardo') }
192
- let!(:artist2) { Artist.create!(name: 'Malevich') }
193
- let!(:artwork1) { Artwork.create!(title: 'Mona Lisa', artist_ids: [artist1.id], published: true) }
194
- let!(:artwork2) { Artwork.create!(title: 'Black Square', artist_ids: [artist2.id], published: false) }
195
- let!(:artwork3) { Artwork.create! }
196
-
197
- it 'counts artworks' do
198
- expect(Artwork.in(artist_ids: artist1.id).count).to eq 1
199
- expect(Artwork.in(artist_ids: artist2.id).count).to eq 1
200
- end
201
-
202
- it 'counts published artworks' do
203
- expect(Artwork.in(artist_ids: artist1.id).published.count).to eq 1
204
- expect(Artwork.in(artist_ids: artist2.id).published.count).to eq 0
205
- end
206
- end
207
- end
@@ -1,105 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Mongoid::Slug::IndexBuilder do
4
- let(:doc) { Class.new.include(Mongoid::Document) }
5
- let(:scope_key) { nil }
6
- let(:by_model_type) { false }
7
- let(:default_locale) { :en }
8
- let(:locales) { nil }
9
-
10
- subject do
11
- if Mongoid::Compatibility::Version.mongoid3?
12
- doc.index_options.to_a
13
- else
14
- doc.index_specifications.map { |spec| [spec.key, spec.options] }
15
- end
16
- end
17
-
18
- before do
19
- allow(I18n).to receive(:default_locale).and_return(default_locale)
20
- Mongoid::Slug::IndexBuilder.build_indexes(doc, scope_key, by_model_type, locales)
21
- end
22
-
23
- context 'when scope_key is set' do
24
- let(:scope_key) { :foo }
25
-
26
- context 'when by_model_type is true' do
27
- let(:by_model_type) { true }
28
-
29
- it { is_expected.to eq [[{ _slugs: 1, foo: 1, _type: 1 }, {}]] }
30
- end
31
-
32
- context 'when by_model_type is false' do
33
- it { is_expected.to eq [[{ _slugs: 1, foo: 1 }, {}]] }
34
- end
35
-
36
- context 'when locale is set' do
37
- let(:default_locale) { :de }
38
- let(:locales) { true }
39
-
40
- it { is_expected.to eq [[{ :'_slugs.de' => 1, foo: 1 }, {}]] }
41
- end
42
-
43
- context 'when locale is not set' do
44
- it { is_expected.to eq [[{ _slugs: 1, foo: 1 }, {}]] }
45
- end
46
-
47
- context 'when locales is an Array' do
48
- let(:locales) { %i[es de fr] }
49
-
50
- it do
51
- is_expected.to eq [[{ :'_slugs.es' => 1, foo: 1 }, {}],
52
- [{ :'_slugs.de' => 1, foo: 1 }, {}],
53
- [{ :'_slugs.fr' => 1, foo: 1 }, {}]]
54
- end
55
- end
56
- end
57
-
58
- context 'when scope_key is not set' do
59
- context 'when by_model_type is true' do
60
- let(:by_model_type) { true }
61
-
62
- it { is_expected.to eq [[{ _slugs: 1, _type: 1 }, {}]] }
63
- end
64
-
65
- context 'when by_model_type is false' do
66
- it { is_expected.to eq [[{ _slugs: 1 }, { unique: true, sparse: true }]] }
67
- end
68
-
69
- context 'when locales is true' do
70
- let(:locales) { true }
71
-
72
- it { is_expected.to eq [[{ :'_slugs.en' => 1 }, { unique: true, sparse: true }]] }
73
- end
74
-
75
- context 'when locales is a String' do
76
- let(:locales) { 'de' }
77
-
78
- it { is_expected.to eq [[{ :'_slugs.de' => 1 }, { unique: true, sparse: true }]] }
79
- end
80
-
81
- context 'when locales is a Symbol' do
82
- let(:locales) { :de }
83
-
84
- it { is_expected.to eq [[{ :'_slugs.de' => 1 }, { unique: true, sparse: true }]] }
85
- end
86
-
87
- context 'when locales is an Array' do
88
- let(:locales) { %i[es de fr] }
89
-
90
- it do
91
- is_expected.to eq [[{ :'_slugs.es' => 1 }, { unique: true, sparse: true }],
92
- [{ :'_slugs.de' => 1 }, { unique: true, sparse: true }],
93
- [{ :'_slugs.fr' => 1 }, { unique: true, sparse: true }]]
94
- end
95
- end
96
-
97
- context 'when locale is set and by_model_type is true' do
98
- let(:locales) { true }
99
- let(:default_locale) { :fr }
100
- let(:by_model_type) { true }
101
-
102
- it { is_expected.to eq [[{ :'_slugs.fr' => 1, _type: 1 }, {}]] }
103
- end
104
- end
105
- end