ActsAsTextcaptcha provides spam protection for your Rails models using logic questions from the excellent TextCAPTCHA web service.
A bot (using something like Mechanize) could by-pass spam protection using a fake question and answer. This was down to the gem exposing the possible answers in a hidden form field. Encryption of the answers only really helped prevent against attacks from the dumbest of spam bots. With a valid question and possible answer combo, POST requests could be constructed to appear valid and submit spam.
Using the built-in Rails session to hold possible answers between requests was a no-go too. Let’s say your app used the default ActionDispatch::Session::CookieStore. An attacker could grab a valid cookie that contained some possible answers to a known question and send that same cookie data (repeatedly) with POST requests containing spam. CSRF won’t help here either (with Mechanize) a valid token can be requested before each POST request.
So it was obvious the possible answers needed to be stored server side, and any reference to associate form requests with the answers needed to be random and dynamic (much like Rails own form_authenticity_token). I settled on using the Rails.cache, it’s available by default and easy to configure. The cache key mutates with each request and cache values only live for 10 minutes.
Finally, I released v4.1 removing various hooks for Rails 2. It is 2014 now (over 4 years since Rails 3 was released) I think its time to move on.