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>

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>

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

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