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.
@@ -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
@@ -1,3 +1,3 @@
1
1
  module FlowmorRouter
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,6 +1,7 @@
1
1
  require "flowmor_router/engine"
2
2
  require "flowmor_router/exceptions"
3
- require "flowmor_router/acts_as_flowmor_routable"
3
+ require "flowmor_router/router_classes"
4
+ require "flowmor_router/acts_as_routable"
4
5
 
5
6
  module FlowmorRouter
6
7
 
@@ -1,3 +1,9 @@
1
1
  class Article < ActiveRecord::Base
2
- acts_as_routable scope: -> { where(published: true) }
2
+ acts_as_routable \
3
+ scope: -> { where(published: true) },
4
+ name: :custom_name
5
+
6
+ def custom_name
7
+ self.title.try(:parameterize) || self.id
8
+ end
3
9
  end
@@ -1,5 +1,5 @@
1
1
  class NewsArticle < ActiveRecord::Base
2
2
  acts_as_routable \
3
- derived_name_field: :caption,
3
+ title_field: :caption,
4
4
  name_field: :slug
5
5
  end
@@ -1,19 +1,20 @@
1
1
  class Post < ActiveRecord::Base
2
2
  belongs_to :category, class_name: "PostCategory", counter_cache: true
3
3
 
4
- acts_as_routable \
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 category_name
13
- category.try(:name) || 'general'
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
- def route
17
- "/#{category_name}/#{name}"
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
@@ -2,6 +2,6 @@ class PostCategory < ActiveRecord::Base
2
2
  has_many :posts, foreign_key: "category_id"
3
3
 
4
4
  acts_as_routable \
5
- controller_action: "blog#category",
6
- route_model: "category"
5
+ :category,
6
+ controller_action: "blog#category"
7
7
  end