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.
@@ -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