None of the other answers worked for me. The best approach I've found for my use case was using the built in Loofah gem:
good = '&'
bad = "<script>alert('I am evil');</script>"
greater_than = '>' # << my use case
Loofah.fragment(good).text(encode_special_chars: false)
# => "&"
Loofah.fragment(greater_than).text(encode_special_chars: false)
# => ">"
Loofah.fragment(bad).text(encode_special_chars: false)
# => "alert('I am evil');"
# And just for clarity, without the option passed in:
Loofah.fragment(good).text
# => "&"
It's not flawless though, so be incredibly careful:
really_bad = "<script>alert('I am evil');</script>"
Loofah.fragment(really_bad).text(encode_special_chars: false)
# => "<script>alert('I am evil');</script>"
More info on the specified method here.
Definitely the most efficient approach for what I needed to do!