Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The solution I ended up with was inspired by both @dsander's answer and @Glex's comment, and uses <a href="http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html" rel="nofollow noreferrer" title="Callbacks">callbacks</a>. I had to first create a <code>name_encoded</code> field (default: <code>false</code>) for the <code>file_spaces</code> table in the database, because already-saved file spaces are not encoded.</p> <p>Then, I created a model to use for callbacks (unfortunately, not the cleanest code):</p> <pre><code>class EncodingWrapper require 'base64' def initialize(attribute) @attribute = attribute.to_s @get_method = @attribute @set_method = @attribute + "=" @get_encoded_method = @attribute + "_encoded" @set_encoded_method = @attribute + "_encoded=" end def before_save(record) set_encoded(record) encode(record) end def after_save(record) decode(record) end # Rails dislikes the after_find callback because it has a potentially # severe performance penalty. So it ignores it unless it is created a # particular way in the model. So I have to change the way this method # works. So long, DRY code. :-/ def self.after_find(record, attribute) # Ugly...but hopefully relatively fast. a = attribute.to_s if record.send(a + '_encoded') record.send(a + '=', Base64.decode64(record.send(a))) end end private def is_encoded?(record) record.send(@get_encoded_method) end def set_encoded(record) record.send(@set_encoded_method, true) end def encode(record) record.send(@set_method, Base64.encode64(record.send(@get_method))) end def decode(record) record.send(@set_method, Base64.decode64(record.send(@get_method))) end end </code></pre> <p>Last, hook the callbacks into the FileSpace model:</p> <pre><code>class FileSpace &lt; ActiveRecord::Base ... before_save EncodingWrapper.new(:name) after_save EncodingWrapper.new(:name) # Have to do the after_find callback special, to tell Rails I'm willing to # pay the performance penalty for this feature. def after_find EncodingWrapper.after_find(self, :name) end ... end </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload