This strikes me as being similar to extracting bits of a model out into modules that then get included back into that model. It looks like you're reducing the complexity of the model, but in fact you're just hiding it elsewhere, without making it any easier to stub things out.
Shameless plug here. If you use the Aspector gem I created, you could move validation logic into an aspect and test it. And apply aspect is very easy. Here is what the code will look like.<p>class Request < ActiveRecord::Base<p>end<p>class RequestValidation < Aspector::Base<p><pre><code> target do
def has_unique_hash_id?
exists?(:hash_id => hash_id)
end
end
before :create do
hash_id = SecureRandom.hex(12) until has_unique_hash_id?
end</code></pre>
end<p>RequestValidation.apply(Request)
You may run into race conditions when two processes end up saving an object with the same hash_id. The check and the object creation should both happen inside a transaction.
I'm kind of curious why you use SecureRandom.hex and then check for uniqueness, rather than just using SecureRandom.uuid?<p>Edit: Nevermind, I realize now that SecureRandom's uuid isn't really a uuid, in that sense. It's just random.