flowmor_router 0.1.1 → 0.2.1
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.
- 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
|