mongoid_slug_mongoid_beta_16_compatible 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.md +94 -0
- data/lib/mongoid/slug.rb +130 -0
- data/lib/mongoid/slug/version.rb +5 -0
- data/spec/models/author.rb +11 -0
- data/spec/models/book.rb +8 -0
- data/spec/models/partner.rb +7 -0
- data/spec/models/person.rb +8 -0
- data/spec/models/relationship.rb +8 -0
- data/spec/models/subject.rb +7 -0
- data/spec/mongoid/slug_spec.rb +287 -0
- data/spec/spec_helper.rb +22 -0
- metadata +167 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Paper Cavalier
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
Mongoid Slug
|
2
|
+
============
|
3
|
+
|
4
|
+
Mongoid Slug generates a URL slug or permalink based on one or more fields in a Mongoid model. It sits on top of [stringex](https://github.com/rsl/stringex) and works with non-Latin characters.
|
5
|
+
|
6
|
+
Quick Start
|
7
|
+
---------------
|
8
|
+
|
9
|
+
First, add mongoid_slug to your Gemfile:
|
10
|
+
|
11
|
+
gem 'mongoid_slug', :require => 'mongoid/slug'
|
12
|
+
|
13
|
+
Say you have a book that embeds many authors. You can set up slugs for both resources like this:
|
14
|
+
|
15
|
+
class Book
|
16
|
+
include Mongoid::Document
|
17
|
+
include Mongoid::Slug
|
18
|
+
field :title
|
19
|
+
slug :title
|
20
|
+
embeds_many :authors
|
21
|
+
end
|
22
|
+
|
23
|
+
class Author
|
24
|
+
include Mongoid::Document
|
25
|
+
include Mongoid::Slug
|
26
|
+
field :first_name
|
27
|
+
field :last_name
|
28
|
+
slug :first_name, :last_name
|
29
|
+
embedded_in :book, :inverse_of => :authors
|
30
|
+
end
|
31
|
+
|
32
|
+
In your controller, you can use the `find_by_slug` helper:
|
33
|
+
|
34
|
+
def find_book
|
35
|
+
Book.find_by_slug(params[:book_id])
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_author
|
39
|
+
@book.authors.find_by_slug(params[:id])
|
40
|
+
end
|
41
|
+
|
42
|
+
To demo some more functionality in the console:
|
43
|
+
|
44
|
+
>> book = Book.create(:title => "A Thousand Plateaus")
|
45
|
+
>> book.to_param
|
46
|
+
"a-thousand-plateaus"
|
47
|
+
>> book.title = "Anti Oedipus"
|
48
|
+
>> book.save
|
49
|
+
>> book.to_param
|
50
|
+
"anti-oedipus"
|
51
|
+
>> author = book.authors.create(:first_name => "Gilles", :last_name => "Deleuze")
|
52
|
+
>> author.to_param
|
53
|
+
=> "gilles-deleuze"
|
54
|
+
>> author.update_attributes(:first_name => "Félix", :last_name => "Guattari")
|
55
|
+
>> author.to_param
|
56
|
+
=> "felix-guattari"
|
57
|
+
|
58
|
+
Scoping by Associations
|
59
|
+
-----------------------
|
60
|
+
|
61
|
+
Objects that are embedded in a parent document automatically have their slug uniqueness scoped to the parent. If you wish to scope by a reference association, you can pass a `:scope` option to the `slug` class method:
|
62
|
+
|
63
|
+
class Company
|
64
|
+
include Mongoid::Document
|
65
|
+
field :name
|
66
|
+
references_many :employees
|
67
|
+
end
|
68
|
+
|
69
|
+
class Employee
|
70
|
+
include Mongoid::Document
|
71
|
+
include Mongoid::Slug
|
72
|
+
field :first_name
|
73
|
+
field :last_name
|
74
|
+
slug :first_name, :last_name, :scope => :company
|
75
|
+
referenced_in :company
|
76
|
+
end
|
77
|
+
|
78
|
+
In this example, if you create an employee without associating it with any company, the slug scope will fall back to the root employees collection. Currently if you have an irregular association name, for instance:
|
79
|
+
|
80
|
+
references_many :employees, :class_name => 'Person', :foreign_key => :company_id
|
81
|
+
|
82
|
+
you **must** specify the `:inverse_of` option on the other side of the assocation.
|
83
|
+
|
84
|
+
Indexing
|
85
|
+
--------
|
86
|
+
|
87
|
+
You may optionally pass an `:index` option to generate an index on the slug in top-level objects.
|
88
|
+
|
89
|
+
class Book
|
90
|
+
field :title
|
91
|
+
slug :title, :index => true
|
92
|
+
end
|
93
|
+
|
94
|
+
Indexes on non-scoped slugs will be unique.
|
data/lib/mongoid/slug.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
require 'stringex'
|
3
|
+
|
4
|
+
module Mongoid #:nodoc:
|
5
|
+
|
6
|
+
# Generates a URL slug or permalink based on one or more fields in a Mongoid
|
7
|
+
# model.
|
8
|
+
module Slug
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
cattr_accessor :slug_name, :slugged_fields, :slug_scope
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
# Sets one ore more fields as source of slug.
|
18
|
+
#
|
19
|
+
# By default, the name of the field that stores the slug is "slug". Pass an
|
20
|
+
# alternative name with the :as option.
|
21
|
+
#
|
22
|
+
# If you wish the slug to be permanent once created, set :permanent to true.
|
23
|
+
#
|
24
|
+
# To index slug in a top-level object, set :index to true.
|
25
|
+
def slug(*fields)
|
26
|
+
options = fields.extract_options!
|
27
|
+
|
28
|
+
self.slug_name = options[:as] || :slug
|
29
|
+
self.slug_scope = options[:scope] || nil
|
30
|
+
self.slugged_fields = fields
|
31
|
+
|
32
|
+
if options[:scoped]
|
33
|
+
ActiveSupport::Deprecation.warn <<-EOM
|
34
|
+
|
35
|
+
The :scoped => true option is deprecated and now default for embedded
|
36
|
+
child documents. Please use :scope => :association_name if you wish
|
37
|
+
to scope by a reference association.
|
38
|
+
EOM
|
39
|
+
end
|
40
|
+
|
41
|
+
field slug_name
|
42
|
+
|
43
|
+
if options[:index]
|
44
|
+
index slug_name, :unique => (slug_scope ? false : true)
|
45
|
+
end
|
46
|
+
|
47
|
+
if options[:permanent]
|
48
|
+
before_create :generate_slug
|
49
|
+
else
|
50
|
+
before_save :generate_slug
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Finds the document with the specified slug or returns nil.
|
55
|
+
def find_by_slug(slug)
|
56
|
+
where(slug_name => slug).first rescue nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_param
|
61
|
+
self.send(slug_name)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
attr_reader :slug_counter
|
67
|
+
|
68
|
+
def build_slug
|
69
|
+
("#{slug_base} #{slug_counter}").to_url
|
70
|
+
end
|
71
|
+
|
72
|
+
def find_unique_slug
|
73
|
+
slug = build_slug
|
74
|
+
if unique_slug?(slug)
|
75
|
+
slug
|
76
|
+
else
|
77
|
+
increment_slug_counter
|
78
|
+
find_unique_slug
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def generate_slug
|
83
|
+
if new_record? || slugged_fields_changed?
|
84
|
+
self.send("#{slug_name}=", find_unique_slug)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def increment_slug_counter
|
89
|
+
@slug_counter = (slug_counter.to_i + 1).to_s
|
90
|
+
end
|
91
|
+
|
92
|
+
def slug_base
|
93
|
+
self.class.slugged_fields.map do |field|
|
94
|
+
self.send(field)
|
95
|
+
end.join(" ")
|
96
|
+
end
|
97
|
+
|
98
|
+
def slugged_fields_changed?
|
99
|
+
self.class.slugged_fields.any? do |field|
|
100
|
+
self.send("#{field}_changed?")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def unique_slug?(slug)
|
105
|
+
uniqueness_scope.where(slug_name => slug).
|
106
|
+
reject { |doc| doc.id == self.id }.
|
107
|
+
empty?
|
108
|
+
end
|
109
|
+
|
110
|
+
def uniqueness_scope
|
111
|
+
if slug_scope
|
112
|
+
metadata = self.class.reflect_on_association(slug_scope)
|
113
|
+
parent = self.send(metadata.name)
|
114
|
+
|
115
|
+
# Make sure doc is actually associated with something, and that some
|
116
|
+
# referenced docs have been persisted to the parent
|
117
|
+
#
|
118
|
+
# TODO: we need better reflection for reference associations, like
|
119
|
+
# association_name instead of forcing collection_name here -- maybe
|
120
|
+
# in the forthcoming Mongoid refactorings?
|
121
|
+
inverse = metadata.inverse_of || collection_name
|
122
|
+
parent.respond_to?(inverse) ? parent.send(inverse) : self.class
|
123
|
+
elsif embedded?
|
124
|
+
_parent.send(association_name)
|
125
|
+
else
|
126
|
+
self.class
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Author
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Slug
|
4
|
+
field :first_name
|
5
|
+
field :last_name
|
6
|
+
slug :first_name, :last_name, :scope => :book, :index => true
|
7
|
+
referenced_in :book
|
8
|
+
references_many :characters,
|
9
|
+
:class_name => 'Person',
|
10
|
+
:foreign_key => :author_id
|
11
|
+
end
|
data/spec/models/book.rb
ADDED
@@ -0,0 +1,287 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
module Mongoid
|
5
|
+
describe Slug do
|
6
|
+
let!(:book) do
|
7
|
+
Book.create(:title => "A Thousand Plateaus")
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when the object is top-level" do
|
11
|
+
it "generates a slug" do
|
12
|
+
book.to_param.should eql "a-thousand-plateaus"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "updates the slug" do
|
16
|
+
book.title = "Anti Oedipus"
|
17
|
+
book.save
|
18
|
+
book.to_param.should eql "anti-oedipus"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "generates a unique slug by appending a counter to duplicate text" do
|
22
|
+
dup = Book.create(:title => book.title)
|
23
|
+
dup.to_param.should eql "a-thousand-plateaus-1"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "does not update slug if slugged fields have not changed" do
|
27
|
+
book.save
|
28
|
+
book.to_param.should eql "a-thousand-plateaus"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "does not change slug if slugged fields have changed but generated slug is identical" do
|
32
|
+
book.title = "a thousand plateaus"
|
33
|
+
book.save
|
34
|
+
book.to_param.should eql "a-thousand-plateaus"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "finds by slug" do
|
38
|
+
Book.find_by_slug(book.to_param).should eql book
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when the object is embedded" do
|
43
|
+
let(:subject) do
|
44
|
+
book.subjects.create(:name => "Psychoanalysis")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "generates a slug" do
|
48
|
+
subject.to_param.should eql "psychoanalysis"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "updates the slug" do
|
52
|
+
subject.name = "Schizoanalysis"
|
53
|
+
subject.save
|
54
|
+
subject.to_param.should eql "schizoanalysis"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "generates a unique slug by appending a counter to duplicate text" do
|
58
|
+
dup = book.subjects.create(:name => subject.name)
|
59
|
+
dup.to_param.should eql 'psychoanalysis-1'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does not update slug if slugged fields have not changed" do
|
63
|
+
subject.save
|
64
|
+
subject.to_param.should eql "psychoanalysis"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "does not change slug if slugged fields have changed but generated slug is identical" do
|
68
|
+
subject.name = "PSYCHOANALYSIS"
|
69
|
+
subject.to_param.should eql "psychoanalysis"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "finds by slug" do
|
73
|
+
book.subjects.find_by_slug(subject.to_param).should eql subject
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when the object is embedded in another embedded object" do
|
78
|
+
let(:person) do
|
79
|
+
Person.create(:name => "John Doe")
|
80
|
+
end
|
81
|
+
|
82
|
+
let(:relationship) do
|
83
|
+
person.relationships.create(:name => "Engagement")
|
84
|
+
end
|
85
|
+
|
86
|
+
let(:partner) do
|
87
|
+
relationship.partners.create(:name => "Jane Smith")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "generates a slug" do
|
91
|
+
partner.to_param.should eql "jane-smith"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "updates the slug" do
|
95
|
+
partner.name = "Jane Doe"
|
96
|
+
partner.save
|
97
|
+
partner.to_param.should eql "jane-doe"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "generates a unique slug by appending a counter to duplicate text" do
|
101
|
+
dup = relationship.partners.create(:name => partner.name)
|
102
|
+
dup.to_param.should eql "jane-smith-1"
|
103
|
+
end
|
104
|
+
|
105
|
+
it "does not update slug if slugged fields have not changed" do
|
106
|
+
partner.save
|
107
|
+
partner.to_param.should eql "jane-smith"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "does not change slug if slugged fields have changed but generated slug is identical" do
|
111
|
+
partner.name = "JANE SMITH"
|
112
|
+
partner.to_param.should eql "jane-smith"
|
113
|
+
end
|
114
|
+
|
115
|
+
it "scopes by parent object" do
|
116
|
+
affair = person.relationships.create(:name => "Affair")
|
117
|
+
lover = affair.partners.create(:name => partner.name)
|
118
|
+
lover.to_param.should eql partner.to_param
|
119
|
+
end
|
120
|
+
|
121
|
+
it "finds by slug" do
|
122
|
+
relationship.partners.find_by_slug(partner.to_param).should eql partner
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when the slug is composed of multiple fields" do
|
127
|
+
let!(:author) do
|
128
|
+
Author.create(
|
129
|
+
:first_name => "Gilles",
|
130
|
+
:last_name => "Deleuze")
|
131
|
+
end
|
132
|
+
|
133
|
+
it "generates a slug" do
|
134
|
+
author.to_param.should eql "gilles-deleuze"
|
135
|
+
end
|
136
|
+
|
137
|
+
it "updates the slug" do
|
138
|
+
author.first_name = "Félix"
|
139
|
+
author.last_name = "Guattari"
|
140
|
+
author.save
|
141
|
+
author.to_param.should eql "felix-guattari"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "generates a unique slug by appending a counter to duplicate text" do
|
145
|
+
dup = Author.create(
|
146
|
+
:first_name => author.first_name,
|
147
|
+
:last_name => author.last_name)
|
148
|
+
dup.to_param.should eql 'gilles-deleuze-1'
|
149
|
+
end
|
150
|
+
|
151
|
+
it "does not update slug if slugged fields have changed but generated slug is identical" do
|
152
|
+
author.last_name = "DELEUZE"
|
153
|
+
author.save
|
154
|
+
author.to_param.should eql 'gilles-deleuze'
|
155
|
+
end
|
156
|
+
|
157
|
+
it "finds by slug" do
|
158
|
+
Author.find_by_slug("gilles-deleuze").should eql author
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when the field name for the slug is set with the :as option" do
|
163
|
+
let(:person) do
|
164
|
+
Person.create(:name => "John Doe")
|
165
|
+
end
|
166
|
+
|
167
|
+
it "sets the slug field name" do
|
168
|
+
person.should respond_to(:permalink)
|
169
|
+
person.permalink.should eql "john-doe"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "when slug is set to be permanent with the :permanent option" do
|
174
|
+
let(:person) do
|
175
|
+
Person.create(:name => "John Doe")
|
176
|
+
end
|
177
|
+
|
178
|
+
it "does not change the slug when the slugged fields are updated" do
|
179
|
+
person.name = "Jane Doe"
|
180
|
+
person.save
|
181
|
+
person.to_param.should eql "john-doe"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "when slug is scoped by a reference association" do
|
186
|
+
let(:author) do
|
187
|
+
book.authors.create(:first_name => "Gilles", :last_name => "Deleuze")
|
188
|
+
end
|
189
|
+
|
190
|
+
it "scopes by parent object" do
|
191
|
+
book2 = Book.create(:title => "Anti Oedipus")
|
192
|
+
dup = book2.authors.create(
|
193
|
+
:first_name => author.first_name,
|
194
|
+
:last_name => author.last_name
|
195
|
+
)
|
196
|
+
dup.to_param.should eql author.to_param
|
197
|
+
end
|
198
|
+
|
199
|
+
it "generates a unique slug by appending a counter to duplicate text" do
|
200
|
+
dup = book.authors.create(
|
201
|
+
:first_name => author.first_name,
|
202
|
+
:last_name => author.last_name)
|
203
|
+
dup.to_param.should eql 'gilles-deleuze-1'
|
204
|
+
end
|
205
|
+
|
206
|
+
context "with an irregular association name" do
|
207
|
+
let(:character) do
|
208
|
+
# well we've got to make up something... :-)
|
209
|
+
author.characters.create(:name => "Oedipus")
|
210
|
+
end
|
211
|
+
|
212
|
+
let!(:author2) do
|
213
|
+
Author.create(
|
214
|
+
:first_name => "Sophocles",
|
215
|
+
:last_name => "son of Sophilos"
|
216
|
+
)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "scopes by parent object provided that inverse_of is specified" do
|
220
|
+
dup = author2.characters.create(:name => character.name)
|
221
|
+
dup.to_param.should eql character.to_param
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
it "works with non-Latin characters" do
|
227
|
+
book.title = "Капитал"
|
228
|
+
book.save
|
229
|
+
book.to_param.should eql "kapital"
|
230
|
+
|
231
|
+
book.title = "Ελλάδα"
|
232
|
+
book.save
|
233
|
+
book.to_param.should eql "ellada"
|
234
|
+
|
235
|
+
book.title = "中文"
|
236
|
+
book.save
|
237
|
+
book.to_param.should eql 'zhong-wen'
|
238
|
+
end
|
239
|
+
|
240
|
+
it "deprecates the :scoped option" do
|
241
|
+
ActiveSupport::Deprecation.should_receive(:warn)
|
242
|
+
class Oldie
|
243
|
+
include Mongoid::Document
|
244
|
+
include Mongoid::Slug
|
245
|
+
field :name
|
246
|
+
slug :name, :scoped => true
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
context "when :index is set to true" do
|
251
|
+
before do
|
252
|
+
Book.collection.drop_indexes
|
253
|
+
Author.collection.drop_indexes
|
254
|
+
end
|
255
|
+
|
256
|
+
it "indexes slug in top-level objects" do
|
257
|
+
Book.create_indexes
|
258
|
+
Book.collection.index_information.should have_key "slug_1"
|
259
|
+
end
|
260
|
+
|
261
|
+
context "when slug is scoped by a reference association" do
|
262
|
+
it "creates a non-unique index" do
|
263
|
+
Author.create_indexes
|
264
|
+
Author.index_information["slug_1"]["unique"].should be_false
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context "when slug is not scoped by a reference association" do
|
269
|
+
it "creates a unique index" do
|
270
|
+
Book.create_indexes
|
271
|
+
Book.index_information["slug_1"]["unique"].should be_true
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
it "does not index slug in embedded objects" do
|
276
|
+
pending "Would such an option even make sense?"
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
context "when :index is not set" do
|
281
|
+
it "does not index slug" do
|
282
|
+
Person.create_indexes
|
283
|
+
Person.collection.index_information.should_not have_key "permalink_1"
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
require "database_cleaner"
|
5
|
+
require "mongoid"
|
6
|
+
require "stringex"
|
7
|
+
require "rspec"
|
8
|
+
|
9
|
+
Mongoid.configure do |config|
|
10
|
+
name = "mongoid_slug_test"
|
11
|
+
config.master = Mongo::Connection.new.db(name)
|
12
|
+
end
|
13
|
+
|
14
|
+
require File.expand_path("../../lib/mongoid/slug", __FILE__)
|
15
|
+
|
16
|
+
Dir["#{File.dirname(__FILE__)}/models/*.rb"].each { |f| require f }
|
17
|
+
|
18
|
+
Rspec.configure do |c|
|
19
|
+
c.before(:all) { DatabaseCleaner.strategy = :truncation }
|
20
|
+
c.before(:each) { DatabaseCleaner.start }
|
21
|
+
c.after(:each) { DatabaseCleaner.clean }
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongoid_slug_mongoid_beta_16_compatible
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
- 1
|
10
|
+
version: 0.5.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Paper Cavalier
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-09 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: mongoid
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 62196477
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
- beta
|
35
|
+
- 15
|
36
|
+
version: 2.0.0.beta.15
|
37
|
+
type: :runtime
|
38
|
+
version_requirements: *id001
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: stringex
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
hash: 31
|
48
|
+
segments:
|
49
|
+
- 1
|
50
|
+
- 2
|
51
|
+
- 0
|
52
|
+
version: 1.2.0
|
53
|
+
type: :runtime
|
54
|
+
version_requirements: *id002
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bson_ext
|
57
|
+
prerelease: false
|
58
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ~>
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
hash: 25
|
64
|
+
segments:
|
65
|
+
- 1
|
66
|
+
- 1
|
67
|
+
- 5
|
68
|
+
version: 1.1.5
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id003
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: database_cleaner
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 7
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
- 6
|
83
|
+
- 0
|
84
|
+
version: 0.6.0
|
85
|
+
type: :development
|
86
|
+
version_requirements: *id004
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: rspec
|
89
|
+
prerelease: false
|
90
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ~>
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
hash: 3
|
96
|
+
segments:
|
97
|
+
- 2
|
98
|
+
- 3
|
99
|
+
- 0
|
100
|
+
version: 2.3.0
|
101
|
+
type: :development
|
102
|
+
version_requirements: *id005
|
103
|
+
description: Mongoid Slug generates a URL slug or permalink based on one or more fields in a Mongoid model.
|
104
|
+
email:
|
105
|
+
- code@papercavalier.com
|
106
|
+
executables: []
|
107
|
+
|
108
|
+
extensions: []
|
109
|
+
|
110
|
+
extra_rdoc_files: []
|
111
|
+
|
112
|
+
files:
|
113
|
+
- lib/mongoid/slug/version.rb
|
114
|
+
- lib/mongoid/slug.rb
|
115
|
+
- LICENSE
|
116
|
+
- README.md
|
117
|
+
- spec/models/author.rb
|
118
|
+
- spec/models/book.rb
|
119
|
+
- spec/models/partner.rb
|
120
|
+
- spec/models/person.rb
|
121
|
+
- spec/models/relationship.rb
|
122
|
+
- spec/models/subject.rb
|
123
|
+
- spec/mongoid/slug_spec.rb
|
124
|
+
- spec/spec_helper.rb
|
125
|
+
has_rdoc: true
|
126
|
+
homepage: http://github.com/papercavalier/mongoid-slug
|
127
|
+
licenses: []
|
128
|
+
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options: []
|
131
|
+
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
hash: 3
|
140
|
+
segments:
|
141
|
+
- 0
|
142
|
+
version: "0"
|
143
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
|
+
none: false
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
hash: 3
|
149
|
+
segments:
|
150
|
+
- 0
|
151
|
+
version: "0"
|
152
|
+
requirements: []
|
153
|
+
|
154
|
+
rubyforge_project: mongoid_slug
|
155
|
+
rubygems_version: 1.5.0
|
156
|
+
signing_key:
|
157
|
+
specification_version: 3
|
158
|
+
summary: Generates a URL slug
|
159
|
+
test_files:
|
160
|
+
- spec/models/author.rb
|
161
|
+
- spec/models/book.rb
|
162
|
+
- spec/models/partner.rb
|
163
|
+
- spec/models/person.rb
|
164
|
+
- spec/models/relationship.rb
|
165
|
+
- spec/models/subject.rb
|
166
|
+
- spec/mongoid/slug_spec.rb
|
167
|
+
- spec/spec_helper.rb
|