<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Drinkingbird: Tag rails</title>
    <link>http://www.drinkingbird.net/blog/articles/tag/rails</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Random keyboard peckings</description>
    <item>
      <title>ActiveRecord Reflective Validation</title>
      <description>&lt;p&gt;So, this is a pretty basic &amp;#8220;for work&amp;#8221; thing I ran into.&lt;/p&gt;

&lt;p&gt;Managers like forms with little red asterisks next to required fields, and there doesn&amp;#8217;t seem to be any straightforward way to query an ActiveRecord class to determine which fields are required.&lt;/p&gt;

&lt;p&gt;Since AR already has to perform the validation, it seemed only right to lump it with the responsibility of keeping track of its own details.&lt;/p&gt;

&lt;p&gt;So far, I&amp;#8217;ve knocked up a small plugin within an existing rails app, which currently deals with presence and uniqueness validations, by providing the methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validates_presence_of?(field)&lt;/li&gt;
&lt;li&gt;validates_uniqueness_of?(field)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;to inspect the model classes.&lt;/p&gt;

&lt;p&gt;Without further ado, here&amp;#8217;s the prototype code:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;ActiveRecord&lt;/span&gt;
  &lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;ReflectiveValidation&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.included&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;mod&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="ident"&gt;mod&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;extend&lt;/span&gt; &lt;span class="constant"&gt;ClassMethods&lt;/span&gt;
      &lt;span class="ident"&gt;validation_methods&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="ident"&gt;arr_name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{method}&lt;/span&gt;_fields&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;.&lt;/span&gt;&lt;span class="ident"&gt;to_sym&lt;/span&gt;
        &lt;span class="ident"&gt;mod&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;class_inheritable_array&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;arr_name&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="ident"&gt;mod&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;write_inheritable_array&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;arr_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;[])&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.validation_methods&lt;/span&gt;
      &lt;span class="punct"&gt;[&lt;/span&gt;
        &lt;span class="symbol"&gt;:validates_presence_of&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
        &lt;span class="symbol"&gt;:validates_uniqueness_of&lt;/span&gt;
      &lt;span class="punct"&gt;]&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;ClassMethods&lt;/span&gt;
      &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;ReflectiveValidation&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="ident"&gt;validation_methods&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="ident"&gt;module_eval&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;
          &lt;span class="punct"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="constant"&gt;eos&lt;/span&gt;&lt;span class="string"&gt;
            def &lt;span class="expr"&gt;#{method}&lt;/span&gt;(*fields)
              write_inheritable_array(:&lt;span class="expr"&gt;#{method}&lt;/span&gt;_fields, fields)
              super(fields)
            end

            def &lt;span class="expr"&gt;#{method}&lt;/span&gt;?(field)
              &lt;span class="expr"&gt;#{method}&lt;/span&gt;_fields.include?(field)
            end
&lt;/span&gt;&lt;span class="constant"&gt;          eos&lt;/span&gt;
        &lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I&amp;#8217;m looking at fleshing it out, handling more validations, and hopefully dealing with things like length requirements.&lt;/p&gt;

&lt;p&gt;Oh, and actually hosting the plugin somewhere.&lt;/p&gt;</description>
      <pubDate>Thu, 05 Jun 2008 01:55:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:c8e27c95-32c3-4144-b43a-f92ab68453aa</guid>
      <author>Chris</author>
      <link>http://www.drinkingbird.net/blog/articles/2008/06/05/activerecord-reflective-validation</link>
      <category>Ruby on Rails</category>
      <category>ActiveRecord</category>
      <category>ruby</category>
      <category>rails</category>
      <category>plugins</category>
    </item>
  </channel>
</rss>
