Lickety-split custom validations in Rails

Have a highly specific, yet custom validation for a particular field on one of your Rails model objects? Don’t want to create a ActiveModel::Validator type? Not a problem!

You can just as easily create a method that can be invoked as part of the validation process. For example, imagine a field dubbed uri in some model object; this field must begin with a protocol (i.e. http or https). You can create a validation method like so:

Custom validator
<span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">uri_should_start_with_protocol</span>
</span><span class='line'>  <span class="k">if</span> <span class="o">!</span><span class="n">uri</span><span class="o">.</span><span class="n">start_with?</span><span class="p">(</span><span class="s1">'http://'</span><span class="p">)</span> <span class="o">&&</span> <span class="o">!</span><span class="n">uri</span><span class="o">.</span><span class="n">start_with?</span><span class="p">(</span><span class="s1">'https://'</span><span class="p">)</span>
</span><span class='line'>    <span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="ss">:uri</span><span class="p">,</span> <span class="s1">'Web Address should start with http:// or https://'</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code>

This method resides in your model. You can then register this method as a validation for your model like so:

Wiring the validation
<span class='line-number'>1</span>
<code class='ruby'><span class='line'><span class="n">validate</span> <span class="ss">:uri_should_start_with_protocol</span>
</span></code>

Now if the uri field doesn’t contain http or https, model.save will return false. Done!

Related:
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.