vanity_slug 0.0.2 → 0.0.3
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/README.md +15 -7
- data/lib/vanity_slug/active_record.rb +17 -16
- data/lib/vanity_slug/version.rb +1 -1
- data/lib/vanity_slug.rb +2 -0
- data/spec/vanity_slug_spec.rb +1 -2
- metadata +1 -1
data/README.md
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
# VanitySlug
|
2
2
|
|
3
|
-
Add unique vanity urls to any model without use of redirects.
|
4
|
-
|
3
|
+
Add unique vanity urls to any model without use of redirects. Middleware matches routes that don't resolve with the Rails router and checks if they match a slug from any vanity-slug enabled model. If found, the env["PATH_INFO"] is changed like so:
|
4
|
+
|
5
|
+
Given a Post with slug "my-post-title" and id 1, and a Category with slug "the-category" and id 2:
|
5
6
|
|
6
7
|
"/my-post-title" => "/posts/1"
|
7
8
|
"/the-category" => "/category/2"
|
8
9
|
|
10
|
+
This lets Rails do the rest of the work.
|
11
|
+
|
9
12
|
## Installation
|
10
13
|
|
11
14
|
Add this line to your application's Gemfile:
|
@@ -26,11 +29,11 @@ Or install it yourself as:
|
|
26
29
|
|
27
30
|
### Options
|
28
31
|
|
29
|
-
* action: route vanity slug will resolve to
|
30
|
-
* field_to_slug: which column to use in vanity slug generation
|
31
|
-
* slug_field: which column to store generated slug
|
32
|
+
* action: route vanity slug will resolve to (default: RESTful show route i.e. "/posts/:id"). Route must be defined.
|
33
|
+
* field_to_slug: which column to use in vanity slug generation (default: :name).
|
34
|
+
* slug_field: which column to store generated slug (default: :slug).
|
32
35
|
* uniqueness_scope: method or attribute to use as uniqueness check in slug
|
33
|
-
generation
|
36
|
+
generation (default: nil).
|
34
37
|
|
35
38
|
#### Config
|
36
39
|
|
@@ -38,7 +41,12 @@ Or install it yourself as:
|
|
38
41
|
VanitySlug.path_scope Proc.new { |env| { } }
|
39
42
|
```
|
40
43
|
|
41
|
-
Use to scope the finder based on rack env, i.e. host parameter.
|
44
|
+
Use to scope the finder based on rack env, i.e. host parameter. Should return a hash suitable for a `where` relational argument.
|
45
|
+
|
46
|
+
### Gotchas
|
47
|
+
|
48
|
+
* no catch all routes may be used in Rails, otherwise the route collision check
|
49
|
+
will always find a matching route
|
42
50
|
|
43
51
|
## Examples:
|
44
52
|
|
@@ -9,7 +9,8 @@ ActiveSupport.on_load :active_record do
|
|
9
9
|
|
10
10
|
opts = {
|
11
11
|
field_to_slug: :name,
|
12
|
-
slug_field: :slug
|
12
|
+
slug_field: :slug,
|
13
|
+
action: "/#{self.to_s.tableize}/:id"
|
13
14
|
}.merge opts
|
14
15
|
|
15
16
|
class_attribute :has_vanity_slug_opts
|
@@ -32,7 +33,7 @@ ActiveSupport.on_load :active_record do
|
|
32
33
|
module InstanceMethods
|
33
34
|
|
34
35
|
def get_vanity_action
|
35
|
-
action = self.class.has_vanity_slug_opts[:action]
|
36
|
+
action = self.class.has_vanity_slug_opts[:action]
|
36
37
|
|
37
38
|
if action.is_a?(Proc)
|
38
39
|
self.instance_eval &action
|
@@ -75,23 +76,13 @@ ActiveSupport.on_load :active_record do
|
|
75
76
|
errors.add :slug, "already exists"
|
76
77
|
end
|
77
78
|
|
78
|
-
if
|
79
|
-
|
80
|
-
if Rails.application.routes.recognize_path(slug)
|
81
|
-
errors.add :slug, "conflicts with another url"
|
82
|
-
end
|
83
|
-
rescue ActionController::RoutingError
|
84
|
-
end
|
79
|
+
if VanitySlug.check_route_collision(slug_to_check)
|
80
|
+
errors.add :slug, "conflicts with another url"
|
85
81
|
end
|
86
82
|
end
|
87
83
|
|
88
84
|
def vanity_slug_exists?(potential_slug)
|
89
|
-
if
|
90
|
-
begin
|
91
|
-
return true if Rails.application.routes.recognize_path(potential_slug)
|
92
|
-
rescue ActionController::RoutingError
|
93
|
-
end
|
94
|
-
end
|
85
|
+
return true if VanitySlug.check_route_collision(potential_slug)
|
95
86
|
|
96
87
|
VanitySlug.classes.any? do |klass|
|
97
88
|
scope = klass.has_vanity_slug_opts[:uniqueness_scope]
|
@@ -128,8 +119,18 @@ ActiveSupport.on_load :active_record do
|
|
128
119
|
|
129
120
|
obj.get_vanity_action + File.extname(path)
|
130
121
|
end
|
131
|
-
end
|
132
122
|
|
123
|
+
def check_route_collision(path)
|
124
|
+
if defined?(Rails)
|
125
|
+
begin
|
126
|
+
return true if Rails.application.routes.recognize_path(path)
|
127
|
+
rescue ActionController::RoutingError
|
128
|
+
false
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
133
134
|
end
|
134
135
|
|
135
136
|
ActiveRecord::Base.extend VanitySlug::ActiveRecord
|
data/lib/vanity_slug/version.rb
CHANGED
data/lib/vanity_slug.rb
CHANGED
data/spec/vanity_slug_spec.rb
CHANGED
@@ -8,8 +8,7 @@ VanitySlug.path_scope = Proc.new{|env|
|
|
8
8
|
class Post < ActiveRecord::Base
|
9
9
|
attr_accessible :title, :site
|
10
10
|
|
11
|
-
has_vanity_slug
|
12
|
-
field_to_slug: :title,
|
11
|
+
has_vanity_slug field_to_slug: :title,
|
13
12
|
uniqueness_scope: :site_id
|
14
13
|
|
15
14
|
belongs_to :site
|