mongoid-slug 6.0.1 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
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