slugoid 0.0.4
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.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +37 -0
- data/README.markdown +93 -0
- data/Rakefile +9 -0
- data/lib/slugoid.rb +4 -0
- data/lib/slugoid/acts/slugoid.rb +60 -0
- data/lib/slugoid/mongoid/criterion/optional.rb +26 -0
- data/lib/slugoid/version.rb +5 -0
- data/slugoid.gemspec +25 -0
- data/test/test_helper.rb +46 -0
- data/test/unit/test_as_slugoid.rb +71 -0
- data/test/unit/test_mongoid_finder.rb +31 -0
- metadata +127 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
slugoid (0.0.3)
|
5
|
+
mongoid (>= 2.0.0.beta.17)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activemodel (3.0.3)
|
11
|
+
activesupport (= 3.0.3)
|
12
|
+
builder (~> 2.1.2)
|
13
|
+
i18n (~> 0.4)
|
14
|
+
activesupport (3.0.3)
|
15
|
+
bson (1.1.4)
|
16
|
+
bson_ext (1.1.4)
|
17
|
+
builder (2.1.2)
|
18
|
+
i18n (0.5.0)
|
19
|
+
mongo (1.1.4)
|
20
|
+
bson (>= 1.1.1)
|
21
|
+
mongoid (2.0.0.beta.20)
|
22
|
+
activemodel (~> 3.0)
|
23
|
+
mongo (~> 1.1)
|
24
|
+
tzinfo (~> 0.3.22)
|
25
|
+
will_paginate (~> 3.0.pre)
|
26
|
+
shoulda (2.11.3)
|
27
|
+
tzinfo (0.3.23)
|
28
|
+
will_paginate (3.0.pre2)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
bson_ext (~> 1.1.1)
|
35
|
+
mongoid (>= 2.0.0.beta.17)
|
36
|
+
shoulda (~> 2.11.3)
|
37
|
+
slugoid!
|
data/README.markdown
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# slugoid
|
2
|
+
|
3
|
+
Whenever you use MongoDB and Mongoid, there's a high chance you will end up preparing your urls
|
4
|
+
with a slug instead of the traditional ids because MongoDB ids are ugly.
|
5
|
+
|
6
|
+
This gem will help you generate slugs in an easy way
|
7
|
+
|
8
|
+
## Compatibility
|
9
|
+
|
10
|
+
So far it works with the Rails 3 version of Mongoid.
|
11
|
+
|
12
|
+
# Installation
|
13
|
+
|
14
|
+
## Rails 3
|
15
|
+
|
16
|
+
Include it in your Gemfile:
|
17
|
+
|
18
|
+
gem 'slugoid'
|
19
|
+
|
20
|
+
And run bundler
|
21
|
+
|
22
|
+
bundle install
|
23
|
+
|
24
|
+
# Usage
|
25
|
+
|
26
|
+
To use it, all you have to do is call *acts_as_slugoid* in your Mongoid::Document
|
27
|
+
|
28
|
+
class Project
|
29
|
+
include Mongoid::Document
|
30
|
+
|
31
|
+
acts_as_slugoid
|
32
|
+
end
|
33
|
+
|
34
|
+
By default, this will declare a field on the Document called :slug and will try to generate the slug from
|
35
|
+
a field called :name.
|
36
|
+
|
37
|
+
## Options
|
38
|
+
|
39
|
+
### :generate_from
|
40
|
+
|
41
|
+
If you want to change the field to generate the slug you can use the :generate_from option:
|
42
|
+
|
43
|
+
class Organization
|
44
|
+
include Mongoid::Document
|
45
|
+
|
46
|
+
field :alternative_name
|
47
|
+
acts_as_slugoid :generate_from => :alternative_name
|
48
|
+
end
|
49
|
+
|
50
|
+
This will generate the slug form a field called :alternative_name.
|
51
|
+
|
52
|
+
### :store_as
|
53
|
+
|
54
|
+
If you want to change the field where the slug is stored you can use the :store_as option:
|
55
|
+
|
56
|
+
class Organization
|
57
|
+
include Mongoid::Document
|
58
|
+
|
59
|
+
field :name
|
60
|
+
acts_as_slugoid :store_as => :alternative_slug
|
61
|
+
end
|
62
|
+
|
63
|
+
Now it will store the slug in a field called :alternative_slug. If the specified field is not defined
|
64
|
+
on the Document it will be automatically declared, so adding:
|
65
|
+
|
66
|
+
field :alternative_slug
|
67
|
+
|
68
|
+
is optional.
|
69
|
+
|
70
|
+
## find
|
71
|
+
|
72
|
+
To make things transparent and easy, by default, the find method of the acts_as_slugoid Documents will look for the object by the slug, not the id.
|
73
|
+
|
74
|
+
So, if you had the Project class configured as the example above:
|
75
|
+
|
76
|
+
@project = Project.create(:name => "Name")
|
77
|
+
|
78
|
+
Project.find(@project.to_param) #=> @project
|
79
|
+
|
80
|
+
If, for any reason, you have to look for the object using its id, you have to be explicit:
|
81
|
+
|
82
|
+
@project = Project.create(:name => "Name")
|
83
|
+
|
84
|
+
Project.find(:first, :conditions => {:_id => @project.id}) #=> @project
|
85
|
+
Project.where(:_id => @project.id) #=> @project
|
86
|
+
|
87
|
+
The *find* behavior for the other Mongoid::Documents remains the same.
|
88
|
+
|
89
|
+
# About the Author
|
90
|
+
|
91
|
+
[Crowd Interactive](http://www.crowdint.com) is an American web design and development company that happens to work in Colima, Mexico.
|
92
|
+
We specialize in building and growing online retail stores. We don’t work with everyone – just companies we believe in. Call us today to see if there’s a fit.
|
93
|
+
Find more info [here](http://www.crowdint.com)!
|
data/Rakefile
ADDED
data/lib/slugoid.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Acts
|
2
|
+
module Slugoid
|
3
|
+
module ClassMethods
|
4
|
+
#
|
5
|
+
# Adds the logic to generate the slug
|
6
|
+
#
|
7
|
+
# Options:
|
8
|
+
#
|
9
|
+
# :generate_from
|
10
|
+
# The name of the field used to generate the slug
|
11
|
+
#
|
12
|
+
# :store_as
|
13
|
+
# The name of the field where the slug will be stored
|
14
|
+
#
|
15
|
+
def acts_as_slugoid(options = {})
|
16
|
+
@acts_as_slugoid_options = {
|
17
|
+
:generate_from => :name,
|
18
|
+
:store_as => :slug
|
19
|
+
}.merge(options)
|
20
|
+
|
21
|
+
generate_from = @acts_as_slugoid_options[:generate_from]
|
22
|
+
store_as = @acts_as_slugoid_options[:store_as]
|
23
|
+
|
24
|
+
class_eval do
|
25
|
+
before_save do
|
26
|
+
generate_slug(generate_from, store_as)
|
27
|
+
end
|
28
|
+
|
29
|
+
field(store_as, :type => String) unless self.respond_to?(store_as)
|
30
|
+
index(store_as)
|
31
|
+
alias_method :to_param!, :to_param
|
32
|
+
|
33
|
+
include InstanceMethods
|
34
|
+
|
35
|
+
def self.acts_as_slugoid_options
|
36
|
+
@acts_as_slugoid_options
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.find_by_slug(slug)
|
40
|
+
where(@acts_as_slugoid_options[:store_as] => slug).first
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method("to_param") do
|
45
|
+
self.send(store_as)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module InstanceMethods
|
51
|
+
def generate_slug(method, slug_field_name)
|
52
|
+
self.send("#{slug_field_name.to_s}=", self.send(method).parameterize)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.included(receiver)
|
57
|
+
receiver::ClassMethods.send :include, ClassMethods
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mongoid::Criterion::Optional
|
2
|
+
#
|
3
|
+
# Overwrite the id method to find objects
|
4
|
+
# by the specified slug rather than the id.
|
5
|
+
# If you want to find via id you'll have to use
|
6
|
+
# An explicit finder like:
|
7
|
+
#
|
8
|
+
# where(:_id => some_id)
|
9
|
+
#
|
10
|
+
alias :id! :id
|
11
|
+
def id(*ids)
|
12
|
+
if @klass.respond_to?(:acts_as_slugoid_options)
|
13
|
+
ids.flatten!
|
14
|
+
if ids.size > 1
|
15
|
+
self.in(
|
16
|
+
@klass.acts_as_slugoid_options[:store_as] => ::BSON::ObjectId.cast!(@klass, ids, @klass.primary_key.nil?)
|
17
|
+
)
|
18
|
+
else
|
19
|
+
@selector[@klass.acts_as_slugoid_options[:store_as]] = ids.first
|
20
|
+
end
|
21
|
+
self
|
22
|
+
else
|
23
|
+
id!(*ids)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/slugoid.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "slugoid/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "slugoid"
|
7
|
+
s.version = Acts::Slugoid::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["David Padilla", "Emmanuel Delgado"]
|
10
|
+
s.email = ["david@crowdint.com", "emmanuel@crowdint.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/slugoid"
|
12
|
+
s.summary = %q{Drop-in solution to pretty urls when using Mongoid}
|
13
|
+
s.description = %q{Drop-in solution to pretty urls when using Mongoid}
|
14
|
+
|
15
|
+
s.add_dependency('mongoid', '>= 2.0.0.beta.17')
|
16
|
+
s.add_development_dependency('shoulda', '~>2.11.3')
|
17
|
+
s.add_development_dependency('bson_ext', '~>1.1.1')
|
18
|
+
|
19
|
+
s.rubyforge_project = "slugoid"
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'shoulda'
|
5
|
+
require 'mongoid'
|
6
|
+
require 'slugoid'
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
9
|
+
|
10
|
+
module Acts::Slugoid::Test
|
11
|
+
module Config
|
12
|
+
def setup
|
13
|
+
::Mongoid.configure do |config|
|
14
|
+
name = "slugoid_test"
|
15
|
+
host = "localhost"
|
16
|
+
config.master = Mongo::Connection.new.db(name)
|
17
|
+
config.logger = nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
::Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Project
|
28
|
+
include Mongoid::Document
|
29
|
+
field :name, :type => String
|
30
|
+
end
|
31
|
+
|
32
|
+
class SlugoidProject
|
33
|
+
include Mongoid::Document
|
34
|
+
field :name, :type => String
|
35
|
+
acts_as_slugoid
|
36
|
+
end
|
37
|
+
|
38
|
+
class Organization
|
39
|
+
include Mongoid::Document
|
40
|
+
|
41
|
+
acts_as_slugoid :generate_from => :alternative_name, :store_as => :alternative_slug
|
42
|
+
|
43
|
+
field :alternative_name, :type => String
|
44
|
+
field :alternative_slug, :type => String
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Acts::Slugoid::Test
|
4
|
+
|
5
|
+
class TestSlugoid < Test::Unit::TestCase
|
6
|
+
|
7
|
+
include Config
|
8
|
+
|
9
|
+
def methods_per_model_assert(expected, model)
|
10
|
+
[:find_by_slug, :find].each do |method|
|
11
|
+
assert_equal(expected, model.send(method, expected.to_param))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "default parameters" do
|
16
|
+
setup do
|
17
|
+
@slugoid_project = SlugoidProject.create(:name => 'Some name')
|
18
|
+
end
|
19
|
+
|
20
|
+
should "create a slug" do
|
21
|
+
assert_equal('some-name', @slugoid_project.slug)
|
22
|
+
end
|
23
|
+
|
24
|
+
context :to_param do
|
25
|
+
should "return the slug too" do
|
26
|
+
assert_equal('some-name', @slugoid_project.to_param)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context :using_finders do
|
31
|
+
should "find the object" do
|
32
|
+
methods_per_model_assert @slugoid_project, SlugoidProject
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "custom parameters" do
|
38
|
+
setup do
|
39
|
+
@organization = Organization.create(:alternative_name => 'Some Other Name')
|
40
|
+
end
|
41
|
+
|
42
|
+
should "create a slug using the custom field and store it on the custom slug field" do
|
43
|
+
assert_equal('some-other-name', @organization.alternative_slug)
|
44
|
+
end
|
45
|
+
|
46
|
+
context :to_param do
|
47
|
+
should "return the slug too" do
|
48
|
+
assert_equal('some-other-name', @organization.to_param)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context :using_finders do
|
53
|
+
should "find the object" do
|
54
|
+
methods_per_model_assert @organization, Organization
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context :acts_as_slugoid_options do
|
60
|
+
should "respond to acts_as_slugoid_options" do
|
61
|
+
assert_equal(true, SlugoidProject.respond_to?(:acts_as_slugoid_options))
|
62
|
+
end
|
63
|
+
|
64
|
+
should "return the options for acts_as_slugoid" do
|
65
|
+
assert_equal(:name, SlugoidProject.acts_as_slugoid_options[:generate_from])
|
66
|
+
assert_equal(:slug, SlugoidProject.acts_as_slugoid_options[:store_as])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Acts::Slugoid::Test
|
4
|
+
|
5
|
+
class TestMongoidFinder < Test::Unit::TestCase
|
6
|
+
|
7
|
+
include Config
|
8
|
+
alias :setup! :setup
|
9
|
+
|
10
|
+
def setup
|
11
|
+
setup!
|
12
|
+
@slugoid_project = SlugoidProject.create!(:name => 'Scott')
|
13
|
+
@project = Project.create!
|
14
|
+
end
|
15
|
+
|
16
|
+
context "find" do
|
17
|
+
should "return the objects when you pass the id" do
|
18
|
+
assert_equal(@slugoid_project, SlugoidProject.find(@slugoid_project.to_param))
|
19
|
+
assert_equal(@project, Project.find(@project.id))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "explicit find by id" do
|
24
|
+
should "return the object" do
|
25
|
+
assert_equal(@slugoid_project, SlugoidProject.where(:_id => @slugoid_project.id).first)
|
26
|
+
assert_equal(@slugoid_project, SlugoidProject.find(:first, :conditions => {:_id => @slugoid_project.id}))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slugoid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- David Padilla
|
13
|
+
- Emmanuel Delgado
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-22 00:00:00 -07: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
|
+
segments:
|
30
|
+
- 2
|
31
|
+
- 0
|
32
|
+
- 0
|
33
|
+
- beta
|
34
|
+
- 17
|
35
|
+
version: 2.0.0.beta.17
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: shoulda
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 11
|
49
|
+
- 3
|
50
|
+
version: 2.11.3
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: bson_ext
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 1
|
64
|
+
- 1
|
65
|
+
version: 1.1.1
|
66
|
+
type: :development
|
67
|
+
version_requirements: *id003
|
68
|
+
description: Drop-in solution to pretty urls when using Mongoid
|
69
|
+
email:
|
70
|
+
- david@crowdint.com
|
71
|
+
- emmanuel@crowdint.com
|
72
|
+
executables: []
|
73
|
+
|
74
|
+
extensions: []
|
75
|
+
|
76
|
+
extra_rdoc_files: []
|
77
|
+
|
78
|
+
files:
|
79
|
+
- .gitignore
|
80
|
+
- Gemfile
|
81
|
+
- Gemfile.lock
|
82
|
+
- README.markdown
|
83
|
+
- Rakefile
|
84
|
+
- lib/slugoid.rb
|
85
|
+
- lib/slugoid/acts/slugoid.rb
|
86
|
+
- lib/slugoid/mongoid/criterion/optional.rb
|
87
|
+
- lib/slugoid/version.rb
|
88
|
+
- slugoid.gemspec
|
89
|
+
- test/test_helper.rb
|
90
|
+
- test/unit/test_as_slugoid.rb
|
91
|
+
- test/unit/test_mongoid_finder.rb
|
92
|
+
has_rdoc: true
|
93
|
+
homepage: http://rubygems.org/gems/slugoid
|
94
|
+
licenses: []
|
95
|
+
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
version: "0"
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
requirements: []
|
118
|
+
|
119
|
+
rubyforge_project: slugoid
|
120
|
+
rubygems_version: 1.3.7
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Drop-in solution to pretty urls when using Mongoid
|
124
|
+
test_files:
|
125
|
+
- test/test_helper.rb
|
126
|
+
- test/unit/test_as_slugoid.rb
|
127
|
+
- test/unit/test_mongoid_finder.rb
|