I use a call to the sanitize method every time I render some user
input, but it would be much nicer if I could clean it up once before
putting it into the database and avoid having to call the (relatively
expensive) sanitize every time I render a page.
My first thought was to just add something like:
def message=(x)
self[:message]=sanitize(x)
end
However, the sanitize helper cannot be called from inside a model. So
what would be an elegant way to do this? Stuffing this inside the
controller seems awkward (and I would have to put it in several
places).
Although I’m against destructive actions on user entered data (if you sanitize before saving, you can never recover what the user initially entered), there’s a plugin that does just that:
Thank you, I actually did stumble onto the two you mentioned after
writing my original post. But it seems acts_as_sanitized is no longer
maintained and xss_terminate is too destructive for my purpose as it
includes itself in base and strips out everything everywhere unless
you tell it not to. I have a lot of models I would need to go over and
I agree I'm also against destructive actions on user entered data
except for the few cases where it would be a real performance boost.
Instead of installing all kinds of plugins, would there be any problem
in simply doing this inside a model:
include ActionView::Helpers::SanitizeHelper
def message=(x)
self[:message]=sanitize(x)
end
If you're willing to add fields to your model, you can get around the
destructive action issue simply by storing the original input along
with the sanitized version. Use the unsanitized field in "edit" forms
and display the sanitized field in "show" views. Use a before_save
callback to do the sanitizing during any edit.
So for instance, to clean up user input for a Comment model, have both
comment_text and comment_html fields, then run comment_text through
RedCloth (if you're using textile), white_list (to clip out nasty
tags), and hpricot (to close open tags) and stuff into comment_html
(via a before_save method). Display comment_html but let the user re-
edit comment_text -- which gets cleaned back up and saved in
comment_html.