Module: Roda::RodaPlugins::ClassMatchers
- Defined in:
- lib/roda/plugins/class_matchers.rb
Overview
The class_matchers plugin allows you do define custom regexps and conversion procs to use for specific classes. For example, if you have multiple routes similar to:
r.on /(\d\d\d\d)-(\d\d)-(\d\d)/ do |y, m, d|
date = Date.new(y.to_i, m.to_i, d.to_i)
# ...
end
You can register a Date class matcher for that regexp:
class_matcher(Date, /(\d\d\d\d)-(\d\d)-(\d\d)/) do |y, m, d|
Date.new(y.to_i, m.to_i, d.to_i)
end
And then use the Date class as a matcher, and it will yield a Date object:
r.on Date do |date|
# ...
end
This is useful to DRY up code if you are using the same type of pattern and type conversion in multiple places in your application. You can have the block return an array to yield multiple captures.
If you have a segment match the passed regexp, but decide during block processing that you do not want to treat it as a match, you can have the block return nil or false. This is useful if you want to make sure you are using valid data:
class_matcher(Date, /(\d\d\d\d)-(\d\d)-(\d\d)/) do |y, m, d|
y = y.to_i
m = m.to_i
d = d.to_i
Date.new(y, m, d) if Date.valid_date?(y, m, d)
end
The second argument to class_matcher can be a class already registered as a class matcher. This can DRY up code that wants a conversion performed by an existing class matcher:
class_matcher Employee, Integer do |id|
Employee[id]
end
With the above example, the Integer matcher performs the conversion to integer, so id is yielded as an integer. The block then looks up the employee with that id. If there is no employee with that id, then the Employee matcher will not match.
If using the symbol_matchers plugin, you can provide a recognized symbol matcher as the second argument to class_matcher, and it will work in a similar manner:
symbol_matcher(:employee_id, /E-(\d{6})/) do |employee_id|
employee_id.to_i
end
class_matcher Employee, :employee_id do |id|
Employee[id]
end
Blocks passed to the class_matchers plugin are evaluated in route block context.
When passing a regexp as a matcher, to class_matcher, you can provide a segment: true option to speed up the matching on Ruby 2.4+:
symbol_matcher(:employee_id, /E-(\d{6})/, segment: true) do |employee_id|
employee_id.to_i
end
Use of segment: true requires that the regexp not match more than one segment (i.e. it cannot match /). Additionally, the entire segment will be captured, so any capture groups in the regexp will be ignored.
This plugin does not work with the params_capturing plugin, as it does not offer the ability to associate block arguments with named keys.
Defined Under Namespace
Modules: ClassMethods, RequestMethods
Class Method Summary collapse
Class Method Details
.configure(app) ⇒ Object
88 89 90 91 92 93 |
# File 'lib/roda/plugins/class_matchers.rb', line 88 def self.configure(app) app.opts[:class_matchers] ||= { Integer=>[/(\d{1,100})/, /\A\/(\d{1,100})(?=\/|\z)/, :_convert_class_Integer].freeze, String=>[/([^\/]+)/, nil, nil].freeze } end |
.load_dependencies(app) ⇒ Object
84 85 86 |
# File 'lib/roda/plugins/class_matchers.rb', line 84 def self.load_dependencies(app) app.plugin :_symbol_class_matchers end |