acts_as_sluggable 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.markdown +19 -0
- data/acts_as_sluggable.gemspec +2 -2
- data/lib/acts_as_sluggable.rb +2 -4
- data/lib/acts_as_sluggable/acts/sluggable.rb +30 -29
- data/lib/acts_as_sluggable/mongoid/criterion/optional.rb +26 -0
- data/lib/acts_as_sluggable/version.rb +1 -1
- data/test/test_helper.rb +38 -2
- data/test/unit/test_as_sluggable.rb +46 -63
- data/test/unit/test_mongoid_finder.rb +31 -0
- metadata +9 -4
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.markdown
CHANGED
@@ -67,6 +67,25 @@ on the Document it will be automatically declared, so adding:
|
|
67
67
|
|
68
68
|
is optional.
|
69
69
|
|
70
|
+
## find
|
71
|
+
|
72
|
+
To make things transparent and easy, by default, the find method of the acts_as_sluggable 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
|
+
|
70
89
|
# About the Author
|
71
90
|
|
72
91
|
[Crowd Interactive](http://www.crowdint.com) is an American web design and development company that happens to work in Colima, Mexico.
|
data/acts_as_sluggable.gemspec
CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "acts_as_sluggable"
|
7
7
|
s.version = Acts::Sluggable::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["David Padilla"]
|
10
|
-
s.email = ["david@crowdint.com"]
|
9
|
+
s.authors = ["David Padilla", "Emmanuel Delgado"]
|
10
|
+
s.email = ["david@crowdint.com", "emmanuel@crowdint.com"]
|
11
11
|
s.homepage = "http://rubygems.org/gems/acts_as_sluggable"
|
12
12
|
s.summary = %q{Create a slug for mongoid documents}
|
13
13
|
s.description = %q{Create a slug for mongoid documents}
|
data/lib/acts_as_sluggable.rb
CHANGED
@@ -16,44 +16,45 @@ module Acts
|
|
16
16
|
@acts_as_sluggable_options = {
|
17
17
|
:generate_from => :name,
|
18
18
|
:store_as => :slug
|
19
|
-
|
19
|
+
}.merge(options)
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
generate_from = @acts_as_sluggable_options[:generate_from]
|
22
|
+
store_as = @acts_as_sluggable_options[:store_as]
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
class_eval do
|
25
|
+
before_save do
|
26
|
+
generate_slug(generate_from, store_as)
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
29
|
+
field(store_as, :type => String) unless self.respond_to?(store_as)
|
30
|
+
index(store_as)
|
31
|
+
alias_method :to_param!, :to_param
|
33
32
|
|
34
|
-
|
35
|
-
self.send(store_as)
|
36
|
-
end
|
37
|
-
end
|
33
|
+
include InstanceMethods
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
def self.acts_as_sluggable_options
|
36
|
+
@acts_as_sluggable_options
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.find_by_slug(slug)
|
40
|
+
where(@acts_as_sluggable_options[:store_as] => slug).first
|
41
|
+
end
|
42
|
+
end
|
42
43
|
|
43
|
-
|
44
|
-
|
44
|
+
define_method("to_param") do
|
45
|
+
self.send(store_as)
|
46
|
+
end
|
47
|
+
end
|
45
48
|
end
|
46
|
-
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
51
54
|
end
|
52
|
-
end
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
def self.included(receiver)
|
57
|
+
receiver::ClassMethods.send :include, ClassMethods
|
58
|
+
end
|
57
59
|
end
|
58
60
|
end
|
59
|
-
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_sluggable_options)
|
13
|
+
ids.flatten!
|
14
|
+
if ids.size > 1
|
15
|
+
self.in(
|
16
|
+
@klass.acts_as_sluggable_options[:store_as] => ::BSON::ObjectId.cast!(@klass, ids, @klass.primary_key.nil?)
|
17
|
+
)
|
18
|
+
else
|
19
|
+
@selector[@klass.acts_as_sluggable_options[:store_as]] = ids.first
|
20
|
+
end
|
21
|
+
self
|
22
|
+
else
|
23
|
+
id!(*ids)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -3,8 +3,44 @@ require 'test/unit'
|
|
3
3
|
require 'bundler/setup'
|
4
4
|
require 'shoulda'
|
5
5
|
require 'mongoid'
|
6
|
-
|
7
6
|
require 'acts_as_sluggable'
|
8
7
|
|
9
|
-
# $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
10
8
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
9
|
+
|
10
|
+
module Acts::Sluggable::Test
|
11
|
+
module Config
|
12
|
+
def setup
|
13
|
+
::Mongoid.configure do |config|
|
14
|
+
name = "acts_as_sluggable_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 SluggableProject
|
33
|
+
include Mongoid::Document
|
34
|
+
field :name, :type => String
|
35
|
+
acts_as_sluggable
|
36
|
+
end
|
37
|
+
|
38
|
+
class Organization
|
39
|
+
include Mongoid::Document
|
40
|
+
|
41
|
+
acts_as_sluggable :generate_from => :alternative_name, :store_as => :alternative_slug
|
42
|
+
|
43
|
+
field :alternative_name, :type => String
|
44
|
+
field :alternative_slug, :type => String
|
45
|
+
end
|
46
|
+
|
@@ -1,88 +1,71 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
|
4
|
-
include Mongoid::Document
|
3
|
+
module Acts::Sluggable::Test
|
5
4
|
|
6
|
-
|
5
|
+
class TestActsAsSluggable < Test::Unit::TestCase
|
7
6
|
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
class Organization
|
12
|
-
include Mongoid::Document
|
13
|
-
|
14
|
-
acts_as_sluggable :generate_from => :alternative_name, :store_as => :alternative_slug
|
7
|
+
include Config
|
15
8
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
class TestActsAsSluggable < Test::Unit::TestCase
|
21
|
-
def setup
|
22
|
-
::Mongoid.configure do |config|
|
23
|
-
name = "acts_as_sluggable_test"
|
24
|
-
host = "localhost"
|
25
|
-
config.master = Mongo::Connection.new.db(name)
|
26
|
-
config.logger = nil
|
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
|
27
13
|
end
|
28
|
-
end
|
29
14
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
15
|
+
context "default parameters" do
|
16
|
+
setup do
|
17
|
+
@sluggable_project = SluggableProject.create(:name => 'Some name')
|
18
|
+
end
|
34
19
|
|
35
|
-
|
36
|
-
|
37
|
-
|
20
|
+
should "create a slug" do
|
21
|
+
assert_equal('some-name', @sluggable_project.slug)
|
22
|
+
end
|
38
23
|
|
39
|
-
|
40
|
-
|
41
|
-
|
24
|
+
context :to_param do
|
25
|
+
should "return the slug too" do
|
26
|
+
assert_equal('some-name', @sluggable_project.to_param)
|
27
|
+
end
|
42
28
|
end
|
43
|
-
end
|
44
29
|
|
45
|
-
|
46
|
-
|
47
|
-
|
30
|
+
context :using_finders do
|
31
|
+
should "find the object" do
|
32
|
+
methods_per_model_assert @sluggable_project, SluggableProject
|
33
|
+
end
|
48
34
|
end
|
49
35
|
end
|
50
|
-
end
|
51
36
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
37
|
+
context "custom parameters" do
|
38
|
+
setup do
|
39
|
+
@organization = Organization.create(:alternative_name => 'Some Other Name')
|
40
|
+
end
|
56
41
|
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
60
45
|
|
61
|
-
|
62
|
-
|
63
|
-
|
46
|
+
context :to_param do
|
47
|
+
should "return the slug too" do
|
48
|
+
assert_equal('some-other-name', @organization.to_param)
|
49
|
+
end
|
64
50
|
end
|
65
|
-
end
|
66
51
|
|
67
|
-
|
68
|
-
|
69
|
-
|
52
|
+
context :using_finders do
|
53
|
+
should "find the object" do
|
54
|
+
methods_per_model_assert @organization, Organization
|
55
|
+
end
|
70
56
|
end
|
71
57
|
end
|
72
|
-
end
|
73
58
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
59
|
+
context :acts_as_sluggable_options do
|
60
|
+
should "respond to acts_as_sluggable_options" do
|
61
|
+
assert_equal(true, SluggableProject.respond_to?(:acts_as_sluggable_options))
|
62
|
+
end
|
78
63
|
|
79
|
-
|
80
|
-
|
81
|
-
|
64
|
+
should "return the options for acts_as_sluggable" do
|
65
|
+
assert_equal(:name, SluggableProject.acts_as_sluggable_options[:generate_from])
|
66
|
+
assert_equal(:slug, SluggableProject.acts_as_sluggable_options[:store_as])
|
67
|
+
end
|
82
68
|
end
|
83
|
-
end
|
84
69
|
|
85
|
-
def teardown
|
86
|
-
::Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
|
87
70
|
end
|
88
|
-
end
|
71
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Acts::Sluggable::Test
|
4
|
+
|
5
|
+
class TestMongoidFinder < Test::Unit::TestCase
|
6
|
+
|
7
|
+
include Config
|
8
|
+
alias :setup! :setup
|
9
|
+
|
10
|
+
def setup
|
11
|
+
setup!
|
12
|
+
@sluggable_project = SluggableProject.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(@sluggable_project, SluggableProject.find(@sluggable_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(@sluggable_project, SluggableProject.where(:_id => @sluggable_project.id).first)
|
26
|
+
assert_equal(@sluggable_project, SluggableProject.find(:first, :conditions => {:_id => @sluggable_project.id}))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_sluggable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- David Padilla
|
14
|
+
- Emmanuel Delgado
|
14
15
|
autorequire:
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-10-
|
19
|
+
date: 2010-10-30 00:00:00 -05:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
@@ -71,6 +72,7 @@ dependencies:
|
|
71
72
|
description: Create a slug for mongoid documents
|
72
73
|
email:
|
73
74
|
- david@crowdint.com
|
75
|
+
- emmanuel@crowdint.com
|
74
76
|
executables: []
|
75
77
|
|
76
78
|
extensions: []
|
@@ -86,9 +88,11 @@ files:
|
|
86
88
|
- acts_as_sluggable.gemspec
|
87
89
|
- lib/acts_as_sluggable.rb
|
88
90
|
- lib/acts_as_sluggable/acts/sluggable.rb
|
91
|
+
- lib/acts_as_sluggable/mongoid/criterion/optional.rb
|
89
92
|
- lib/acts_as_sluggable/version.rb
|
90
93
|
- test/test_helper.rb
|
91
94
|
- test/unit/test_as_sluggable.rb
|
95
|
+
- test/unit/test_mongoid_finder.rb
|
92
96
|
has_rdoc: true
|
93
97
|
homepage: http://rubygems.org/gems/acts_as_sluggable
|
94
98
|
licenses: []
|
@@ -126,3 +130,4 @@ summary: Create a slug for mongoid documents
|
|
126
130
|
test_files:
|
127
131
|
- test/test_helper.rb
|
128
132
|
- test/unit/test_as_sluggable.rb
|
133
|
+
- test/unit/test_mongoid_finder.rb
|