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