Archives
Tags
- General (13)
- Food (1)
- Cooking (1)
- Ruby (6)
- Rails (2)
- Svn (2)
- Linux (8)
- Git (1)
- Firefox (7)
- Porn (1)
- Freyja (1)
- Witchhammer (4)
- Music (1)
- Merb (3)
- Poetry (0)
- Bolverk (3)
- Sinatra (1)
- Discogs (1)
- Centos (1)
- Python (1)
- Whinging (1)
- Travel (2)
- Scheme (4)
- Lisp (4)
- Sicp (1)
- Rot13 (1)
- Czech (1)
- Metal (1)
- Passenger (1)
REST-mapping anchor elements in Merb
One of the things I liked about the REST implementation in Rails was the ability to use an anchor to fire off a HTTP "PUT" or "DELETE" request (or, rather the illusion of such) using the link_to helper method. It basically generates a chunk of inline JavaScript in the anchors onclick event that constructs a POST form, adds a few hidden elements, and finally submits it.
I noticed the functionality was not implemented in Merb. This is not totally surprising to me. I mean, inline JavaScript is never pretty. It also means we are relying on Javascript for the link to work correctly.
Regardless of my initial inhibitions, I decided to implement the functionality into a Merb application I was working on. The main chunk came down to this mixin to Merb::AssetsMixin:
module Merb
module AssetsMixin
alias_method :orig_link_to, :link_to
def link_to(name, url='', opts={})
if opts.include?(:method)
method = opts.delete(:method)
if [ :put, :delete ].include? method
opts[:onclick] = "var f = document.createElement('form'); f.style.display = 'none'; " +
"this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href; " +
"var m = document.createElement('input'); m.setAttribute('type', 'hidden'); " +
"m.setAttribute('name', '_method'); m.setAttribute('value', '#{method}'); " +
"f.appendChild(m);f.submit(); return false;"
else
raise ArgumentError, "The :method option only accepts :put or :delete."
end
end
orig_link_to name, url, opts
end
end
endIt mimicks Rails behaviour. Therefore, I call it like this:
link_to "Delete", url(:post, 1), :method => :delete # OR link_to "Save changes", url(:post, 1), :method => :put
I also wrote a bunch of specs and threw it up on GitHub. Eventually, I plan to set it (and the rest of my hacks) up as proper Merb plugins. If anyone wants to give me a hand, feel free to fork the project(s) and do your thing...