flowmor_router 0.1.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +212 -38
- data/Rakefile +0 -2
- data/config/routes.rb +12 -18
- data/lib/flowmor_router/acts_as_routable.rb +56 -0
- data/lib/flowmor_router/exceptions.rb +1 -0
- data/lib/flowmor_router/foo.rb +63 -0
- data/lib/flowmor_router/proxy_foo.rb +50 -0
- data/lib/flowmor_router/router_classes.rb +261 -0
- data/lib/flowmor_router/version.rb +1 -1
- data/lib/flowmor_router.rb +2 -1
- data/test/dummy/app/models/article.rb +7 -1
- data/test/dummy/app/models/news_article.rb +1 -1
- data/test/dummy/app/models/post.rb +12 -11
- data/test/dummy/app/models/post_category.rb +2 -2
- data/test/dummy/log/test.log +86734 -0
- data/test/dummy/test/integration/routable_records_test.rb +2 -1
- data/test/dummy/test/models/article_test.rb +16 -15
- data/test/dummy/test/models/news_article_test.rb +11 -24
- data/test/dummy/test/models/post_category_test.rb +4 -29
- data/test/dummy/test/models/post_test.rb +10 -40
- data/test/router_classes_test.rb +219 -0
- metadata +8 -3
- data/lib/flowmor_router/acts_as_flowmor_routable.rb +0 -122
@@ -0,0 +1,261 @@
|
|
1
|
+
module FlowmorRouter
|
2
|
+
#
|
3
|
+
# class Post < ActiveRecord::Base
|
4
|
+
# acts_as_routable
|
5
|
+
# end
|
6
|
+
#
|
7
|
+
# route_prefix = ''
|
8
|
+
# actor = posts
|
9
|
+
# route_name = posts_title_me_silly
|
10
|
+
# route_path = posts_title_me_silly_path
|
11
|
+
# route_url = posts_title_me_silly_url
|
12
|
+
# @post.path = /posts/title-me-silly
|
13
|
+
# @post.url = http://example.com/posts/title-me-silly
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# class Post < ActiveRecord::Base
|
17
|
+
# acts_as_routable :ramblings
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# route_prefix = ''
|
21
|
+
# actor = ramblings
|
22
|
+
# route_name = ramblings_title_me_silly
|
23
|
+
# route_path = ramblings_title_me_silly_path
|
24
|
+
# route_url = ramblings_title_me_silly_url
|
25
|
+
# @post.path = /ramblings/title-me-silly
|
26
|
+
# @post.url = http://example.com/ramblings/title-me-silly
|
27
|
+
#
|
28
|
+
#
|
29
|
+
# class Post < ActiveRecord::Base
|
30
|
+
# acts_as_routable :ramblings, prefix: :posts
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# route_prefix = posts
|
34
|
+
# actor = ramblings
|
35
|
+
# route_name = posts_ramblings_title_me_silly
|
36
|
+
# route_path = posts_ramblings_title_me_silly_path
|
37
|
+
# route_url = posts_ramblings_title_me_silly_url
|
38
|
+
# @post.path = /posts/ramblings/title-me-silly
|
39
|
+
# @post.url = http://example.com/posts/ramblings/title-me-silly
|
40
|
+
#
|
41
|
+
#
|
42
|
+
# class Post < ActiveRecord::Base
|
43
|
+
# acts_as_routable :ramblings, prefix: [:blog, :posts]
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# route_prefix = blog_posts
|
47
|
+
# actor = ramblings
|
48
|
+
# route_name = blog_posts_ramblings_title_me_silly
|
49
|
+
# route_path = blog_posts_ramblings_title_me_silly_path
|
50
|
+
# route_url = blog_posts_ramblings_title_me_silly_url
|
51
|
+
# @post.path = /blog/posts/ramblings/title-me-silly
|
52
|
+
# @post.url = http://example.com/blog/posts/ramblings/title-me-silly
|
53
|
+
#
|
54
|
+
#
|
55
|
+
# class Post < ActiveRecord::Base
|
56
|
+
# belongs_to :category
|
57
|
+
# acts_as_routable :ramblings, prefix: -> { category.name }
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# route_prefix = blog_posts
|
61
|
+
# actor = ramblings
|
62
|
+
# route_name = silly_category_ramblings_title_me_silly
|
63
|
+
# route_path = silly_category_ramblings_title_me_silly_path
|
64
|
+
# route_url = silly_category_ramblings_title_me_silly_url
|
65
|
+
# @post.path = /silly-category/posts/ramblings/title-me-silly
|
66
|
+
# @post.url = http://example.com/silly-category/posts/ramblings/title-me-silly
|
67
|
+
#
|
68
|
+
#
|
69
|
+
# class Post < ActiveRecord::Base
|
70
|
+
# acts_as_routable
|
71
|
+
# acts_as_routable :archive, prefix: [:posts]
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# route_prefix = ''
|
75
|
+
# actor = posts
|
76
|
+
# route_name = posts_title_me_silly
|
77
|
+
# route_path = posts_title_me_silly_path
|
78
|
+
# route_url = posts_title_me_silly_url
|
79
|
+
# @post.path = /posts/title-me-silly
|
80
|
+
# @post.url = http://example.com/posts/title-me-silly
|
81
|
+
#
|
82
|
+
# AND
|
83
|
+
#
|
84
|
+
# route_prefix = posts
|
85
|
+
# actor = archive
|
86
|
+
# route_name = posts_archive_title_me_silly
|
87
|
+
# route_path = posts_archive_title_me_silly_path
|
88
|
+
# route_url = posts_archive_title_me_silly_url
|
89
|
+
# @post.posts_archive_path = /posts/archive/title-me-silly
|
90
|
+
# @post.posts_archive_url = http://example.com/posts/archive/title-me-silly
|
91
|
+
#
|
92
|
+
class RouterClasses
|
93
|
+
|
94
|
+
@@router_classes = []
|
95
|
+
|
96
|
+
def self.register actor, model, options
|
97
|
+
router_class = RouterClasses.new(actor, model, options)
|
98
|
+
@@router_classes << router_class
|
99
|
+
return router_class
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.unregister model
|
103
|
+
@@router_classes.select{ |s| s.model == model }.each do |item|
|
104
|
+
@@router_classes.delete(item)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.router_classes
|
109
|
+
@@router_classes
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.each &block
|
113
|
+
@@router_classes.each{ |rc| yield rc }
|
114
|
+
end
|
115
|
+
|
116
|
+
attr_reader :actor, :model
|
117
|
+
attr_reader :prefix, :suffix, :controller_action, :no_conflict
|
118
|
+
attr_reader :name_field_attribute, :title_field_attribute
|
119
|
+
attr_reader :custom_route, :custom_name, :delimiter
|
120
|
+
|
121
|
+
def initialize actor, model, options
|
122
|
+
@actor = actor.to_s
|
123
|
+
@model = model
|
124
|
+
|
125
|
+
@name_field_attribute = :name
|
126
|
+
@title_field_attribute = :title
|
127
|
+
|
128
|
+
previous = @@router_classes.detect{|rc| rc.model == @model}
|
129
|
+
raise DuplicateRouterActors.new("duplicate actors registered!") if previous.try(:route_route) == actor
|
130
|
+
@no_conflict = !!previous
|
131
|
+
|
132
|
+
@controller_action = options[:controller_action] || "#{actor}#show"
|
133
|
+
@name_field_attribute = options[:name_field] || :name
|
134
|
+
@title_field_attribute = options[:title_field] || :title
|
135
|
+
@custom_route = options[:route]
|
136
|
+
@custom_name = options[:name]
|
137
|
+
@prefix = options[:prefix] if options[:prefix]
|
138
|
+
@suffix = options[:suffix] if options[:suffix]
|
139
|
+
@delimiter = options[:delimiter] || "-"
|
140
|
+
end
|
141
|
+
|
142
|
+
def default_url_options
|
143
|
+
{ :host => Thread.current[:host], :port => Thread.current[:port] }
|
144
|
+
end
|
145
|
+
|
146
|
+
def no_conflict_model_name
|
147
|
+
return unless no_conflict
|
148
|
+
@model.name.underscore.downcase.split("/").last.pluralize
|
149
|
+
end
|
150
|
+
|
151
|
+
def route_base_name
|
152
|
+
@route_base_name ||= [no_conflict_model_name, actor].compact.join("_")
|
153
|
+
end
|
154
|
+
|
155
|
+
def route_base_path
|
156
|
+
@route_base_path ||= "/" + actor
|
157
|
+
end
|
158
|
+
|
159
|
+
def scope_name
|
160
|
+
"flowmor_#{route_base_name}_routable"
|
161
|
+
end
|
162
|
+
|
163
|
+
def routable
|
164
|
+
@model.send scope_name
|
165
|
+
end
|
166
|
+
|
167
|
+
def to_param value
|
168
|
+
return unless value
|
169
|
+
value.downcase.gsub(/[^\w\s\d\_\-]/,'').gsub(/\s\s+/,' ').gsub(/[^\w\d]/, delimiter)
|
170
|
+
end
|
171
|
+
|
172
|
+
def named_instance method = "router_class"
|
173
|
+
"flowmor_#{route_base_name}_#{method}"
|
174
|
+
end
|
175
|
+
|
176
|
+
def name_field record
|
177
|
+
record.send(name_field_attribute)
|
178
|
+
end
|
179
|
+
|
180
|
+
def title_field record
|
181
|
+
record.send(title_field_attribute)
|
182
|
+
end
|
183
|
+
|
184
|
+
def name record
|
185
|
+
name = record.send(custom_name) if custom_name
|
186
|
+
name ||= name_field(record) || to_param(title_field(record))
|
187
|
+
raise UnroutableRecord if name.to_s.strip.blank?
|
188
|
+
return name
|
189
|
+
end
|
190
|
+
|
191
|
+
def route_suffix record
|
192
|
+
return if @suffix.nil?
|
193
|
+
Array(@suffix.is_a?(Proc) ? record.send(suffix.call) : @suffix)
|
194
|
+
end
|
195
|
+
|
196
|
+
def route_name_suffix record
|
197
|
+
return if @suffix.nil?
|
198
|
+
route_suffix(record).join("_") + "_"
|
199
|
+
end
|
200
|
+
|
201
|
+
def route_path_suffix record
|
202
|
+
return if @suffix.nil?
|
203
|
+
"/" + route_suffix(record).join("/")
|
204
|
+
end
|
205
|
+
|
206
|
+
def route_prefix record
|
207
|
+
return if @prefix.nil?
|
208
|
+
Array(@prefix.is_a?(Proc) ? record.send(prefix.call) : @prefix)
|
209
|
+
end
|
210
|
+
|
211
|
+
def route_name_prefix record
|
212
|
+
return if @prefix.nil?
|
213
|
+
route_prefix(record).join("_") + "_"
|
214
|
+
end
|
215
|
+
|
216
|
+
def route_path_prefix record
|
217
|
+
return if @prefix.nil?
|
218
|
+
"/" + route_prefix(record).join("/")
|
219
|
+
end
|
220
|
+
|
221
|
+
def route_name record
|
222
|
+
"#{route_name_prefix(record)}#{route_base_name}_#{route_name_suffix(record)}#{name(record)}".underscore.parameterize("_")
|
223
|
+
end
|
224
|
+
|
225
|
+
def route_path record
|
226
|
+
if custom_route
|
227
|
+
record.send(custom_route)
|
228
|
+
else
|
229
|
+
"#{route_path_prefix(record)}#{route_base_path}#{route_path_suffix(record)}/#{name(record)}"
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def route_name_method_name
|
234
|
+
no_conflict ? "#{route_base_name}_route_name" : "route_name"
|
235
|
+
end
|
236
|
+
|
237
|
+
def url_method_name
|
238
|
+
no_conflict ? "#{actor}_url" : "url"
|
239
|
+
end
|
240
|
+
|
241
|
+
def path_method_name
|
242
|
+
no_conflict ? "#{actor}_path" : "path"
|
243
|
+
end
|
244
|
+
|
245
|
+
def path record
|
246
|
+
begin
|
247
|
+
Rails.application.routes.url_helpers.send("#{route_name(record)}_path")
|
248
|
+
rescue NoMethodError
|
249
|
+
raise FlowmorRouter::UnroutedRecord.new("[#{route_name(record)}] #{record.inspect} was not routed.")
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def url record
|
254
|
+
begin
|
255
|
+
Rails.application.routes.url_helpers.send("#{route_name(record)}_url", default_url_options)
|
256
|
+
rescue NoMethodError
|
257
|
+
raise FlowmorRouter::UnroutedRecord.new("[#{route_name(record)}] #{record.inspect} was not routed.")
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
data/lib/flowmor_router.rb
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
class Post < ActiveRecord::Base
|
2
2
|
belongs_to :category, class_name: "PostCategory", counter_cache: true
|
3
3
|
|
4
|
-
|
5
|
-
controller_action: "blog#show"
|
6
|
-
|
7
|
-
# Appending category name to the route name prefix
|
8
|
-
def route_name_prefix
|
9
|
-
super + "_#{category_name}"
|
10
|
-
end
|
4
|
+
before_save :populate_name
|
11
5
|
|
12
|
-
def
|
13
|
-
|
6
|
+
def populate_name
|
7
|
+
self.name = self.title.to_s.downcase.gsub(/[^\w\s\d\_\-]/,'').gsub(/\s\s+/,' ').gsub(/[^\w\d]/, '-')
|
14
8
|
end
|
15
9
|
|
16
|
-
|
17
|
-
"
|
10
|
+
acts_as_routable \
|
11
|
+
controller_action: "blog#show",
|
12
|
+
prefix: :by_category,
|
13
|
+
suffix: -> { :category_name }
|
14
|
+
|
15
|
+
acts_as_routable :archive
|
16
|
+
|
17
|
+
def category_name
|
18
|
+
self.category.try(:name) || 'general'
|
18
19
|
end
|
19
20
|
end
|