Easy Rails Patching
If you need to extend Rails for whatever reason, here’s a quick tip. Simply add your Ruby code to the config/initializers folder. Rails initializers (available since Rails 2 came out) are loaded after the Rails framework and plugins, so any custom script executed at this stage will be last.
Here’s an example patch which makes “:disable_with” play nicely with the submit_tag when a remote form tag is used*.
module ActionView module Helpers module FormTagHelper def submit_tag(value = "Save changes", options = {}) options.stringify_keys! if disable_with = options.delete("disable_with") disable_with = "this.value='#{disable_with}'" disable_with << ";#{options.delete('onclick')}" if options['onclick'] disable_with << ";result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())" disable_with << ";if (result == false && this.form.onsubmit && (this.form.onsubmit+'').indexOf('Ajax.Request') == -1) { this.value = this.getAttribute('originalValue'); this.disabled = false }" disable_with << ";return result" options["onclick"] = [ "this.setAttribute('originalValue', this.value)", "this.disabled=true", disable_with ].join(";") end if confirm = options.delete("confirm") options["onclick"] ||= '' options["onclick"] += "return #{confirm_javascript_function(confirm)};" end tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys) end end end end
Be sure you restart your Rails app in order to see your patch take effect.
The above example overrides the existing Rails framework helper. However, you can also use the same technique to extend methods via alias_method_chain.
*The Rails remote_form_for tag adds a ‘return false’ to the form’s onsubmit event handler. However, the Rails submit_tag helper evaluates whether false was returned via onsubmit and will revert back to the original text (and re-enable the button) if this is the case. This makes sense when you are validating a form… the validation fails and you need everything reset so that you can correct your error and resubmit the form. However, for remote forms, in which an AJAX call is made to submit the form, we want the RJS response to drive the form’s (and page’s) behavior. So the patch evaluates whether an AJAX call is made during onsubmit; if so, it lets the submit button stay disabled. Hacky, I know. But it allows us to do what we need without having to touch the PrototypeHelper module. I tested with normal form_tag’s that use disable_with and it works in both cases.
About this entry
Posted: Saturday, October 18th, 2008 at 3:58 pm
- Author:
- Phil Misiowiec
- Tags:
- patching, ruby on rails
- License:
- Creative Commons

No comments
Jump to comment form | comments rss | trackback uri