Rails Magazine - Issue 3
Rails Magazine - Issue 3
Rails Magazine - Issue 3
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
30<br />
Ruby Web Frameworks: A Dive into Waves by Carlo Pecchia<br />
30<br />
So, let’s generate a resource for items:<br />
## resources/item.rb<br />
module TodoManager<br />
module Resources<br />
class Item < Default<br />
end<br />
end<br />
end<br />
# ‘GET /items’<br />
on(:get, [‘items’]) do<br />
items = controller.all<br />
view.list(:items => items)<br />
end<br />
and keep resources/map.rb smaller:<br />
## resources/map.rb<br />
module TodoManager<br />
module Resources<br />
class Map<br />
include Waves::Resources::Mixin<br />
# redirect ‘/’ request do ‘/items’<br />
on ( :get, [] ) { redirect ‘/items’ }<br />
# delegate to item resource any path<br />
like ‘/items’<br />
on (true, [“items”]) { to :item }<br />
# delegate to item resource any path<br />
like ‘/items/’<br />
on (true, [“items”, true]) { to :item }<br />
end<br />
end<br />
end<br />
Hitting the refresh button on our browser shows us that<br />
everything works as expected.<br />
Now we can inject the full REST behaviour to our “item”<br />
resource.<br />
Let’s add the handling for GET /items/ in resources/item.<br />
rb:<br />
# ‘GET /items/’<br />
on(:get, [‘items’, :name]) do<br />
item = controller.find(captured.name)<br />
view.show(:item => item)<br />
end<br />
And see how it is rendered in our browser:<br />
So it’s easy to continue defining all the other “REST methods”<br />
(exercise for the readers!). Don’t forget that the PUT and<br />
DELETE methods are not currently supported by the browsers,<br />
so one of the best way is to mimic them with POST and some<br />
hidden parameters (that is the way it is done in <strong>Rails</strong>, for<br />
instance).<br />
Basically here we can see how routing works. A path is<br />
defined as an array of “chunks”:<br />
# /items/past/1234<br />
[ “items”, “past”, {:name => /\d+/} ]<br />
# /items/some-slug-here/and_something_else<br />
[ “items”, “past”, :name ]<br />
Conclusion<br />
As promised before, we’d like to shortly show how the DSL<br />
for defining routes work. Well, it’s based on the concept of<br />
“Functor”:<br />
fib = Functor.new do<br />
given( 0 ) { 1 }<br />
given( 1 ) { 1 }<br />
given( Integer ) do |n|<br />
self.call( n-1 ) + self.call( n-2 )<br />
end<br />
end<br />
So we can easily create a “request functor”, that is a functor<br />
defined on a resource class to match a given request pattern.<br />
So, for example:<br />
class Item<br />
include Waves::Resources::Mixin<br />
on( :get, [‘name’] ) { “default item<br />
here” }<br />
end