<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.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>acts_as_developer: Validating Mutually-Exclusive Attributes</title>
    <link>http://www.robertshowalter.com/articles/2007/09/16/validating-mutually-exclusive-attributes</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Validating Mutually-Exclusive Attributes</title>
      <description>&lt;p&gt;Let&amp;#8217;s say you have a model that holds a location, with a &amp;#8220;state&amp;#8221; and a &amp;#8220;country&amp;#8221;. Suppose that you want the user to enter &lt;strong&gt;either&lt;/strong&gt; a state or a country, &lt;strong&gt;but not both&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;Your first instinct might be to do something like this:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;validates_presence_of&lt;/span&gt; &lt;span class="symbol"&gt;:state&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:if&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;country&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;blank?&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;validates_presence_of&lt;/span&gt; &lt;span class="symbol"&gt;:country&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:if&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;state&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;blank?&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;That&amp;#8217;s not quite right however. You won&amp;#8217;t get an error if &lt;strong&gt;both&lt;/strong&gt; a state and a country are entered. Furthermore, if both attributes are entered, which one should be considered &amp;#8220;wrong&amp;#8221;?&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s where the generic &lt;code&gt;validate&lt;/code&gt; method can help. Rather than validating a specific attribute, &lt;code&gt;validate&lt;/code&gt; works on the whole row. If you need to add error messages you use the &lt;code&gt;ActiveRecord::Errors#add()&lt;/code&gt; and &lt;code&gt;#add_to_base()&lt;/code&gt; methods.&lt;/p&gt;


	&lt;p&gt;The validation for our state/country example looks like this:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;validate&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;row&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;state&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;blank?&lt;/span&gt; ^ &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;country&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;blank?&lt;/span&gt;
    &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;errors&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_to_base&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Either a state or a country is required (but not both)&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Note how &lt;code&gt;validate&lt;/code&gt; takes a block. The row being saved is passed to the block. The caret (&lt;code&gt;^&lt;/code&gt;) is Ruby&amp;#8217;s &amp;#8220;exclusive-or&amp;#8221; operator. It returns true only if exactly one of its operands is true, which fits our requirements perfectly.&lt;/p&gt;


	&lt;p&gt;The &lt;code&gt;add_to_base&lt;/code&gt; method adds an error message to the list of errors for the row, but the message is not specific to any single attribute. In this case, the error relates to two attributes, so I chose to use &lt;code&gt;add_to_base&lt;/code&gt;.&lt;/p&gt;</description>
      <pubDate>Sun, 16 Sep 2007 15:47:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:11ae682b-32dc-4f41-b07b-1d7c39e27bc5</guid>
      <author>Bob Showalter</author>
      <link>http://www.robertshowalter.com/articles/2007/09/16/validating-mutually-exclusive-attributes</link>
      <category>Rails</category>
      <category>validation</category>
    </item>
    <item>
      <title>"Validating Mutually-Exclusive Attributes" by rssnewsdigest</title>
      <description>&lt;p&gt;Try rssnewsdigest.com, a new comprehensive news aggregator. With rssnewsdigest, you don &#8217;t really have to go anywhere else.
    &lt;a href="http://rssnewsdigest.com" rel="nofollow"&gt;http://rssnewsdigest.com&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 03 Apr 2008 09:05:47 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:51315707-4da9-43b7-9256-173bcaccacaf</guid>
      <link>http://www.robertshowalter.com/articles/2007/09/16/validating-mutually-exclusive-attributes#comment-943</link>
    </item>
    <item>
      <title>"Validating Mutually-Exclusive Attributes" by Bob</title>
      <description>&lt;p&gt;nioloash: I think the main advantage of using the validate class method with a block is that you can specify it multiple times, which allows you to logically separate your validations.&lt;/p&gt;


	&lt;p&gt;Other than that there is no real advantage.&lt;/p&gt;</description>
      <pubDate>Sun, 30 Sep 2007 16:47:45 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:c32a2a5c-21e9-4860-bba4-55c217401c54</guid>
      <link>http://www.robertshowalter.com/articles/2007/09/16/validating-mutually-exclusive-attributes#comment-922</link>
    </item>
    <item>
      <title>"Validating Mutually-Exclusive Attributes" by nicolash</title>
      <description>&lt;p&gt;Could you explain how the giving a block is more useful then to validate without?
Where is it different to:&lt;/p&gt;


	&lt;p&gt;def validate 
 if name.blank? &amp;#38;&amp;#38; email.blank? 
  errors.add_to_base(&amp;#8220;You must specify a name or an email address&amp;#8221;) 
 end 
end&lt;/p&gt;</description>
      <pubDate>Thu, 27 Sep 2007 07:23:01 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:05554477-3b6a-49a4-9102-b92cd4ac9962</guid>
      <link>http://www.robertshowalter.com/articles/2007/09/16/validating-mutually-exclusive-attributes#comment-921</link>
    </item>
    <item>
      <title>"Validating Mutually-Exclusive Attributes" by Bob</title>
      <description>&lt;p&gt;chad: no, this validate method has been around since the early days of Rails.&lt;/p&gt;</description>
      <pubDate>Fri, 21 Sep 2007 08:45:09 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:be212849-c71e-4b1d-ad0d-ab3c982a3227</guid>
      <link>http://www.robertshowalter.com/articles/2007/09/16/validating-mutually-exclusive-attributes#comment-920</link>
    </item>
    <item>
      <title>"Validating Mutually-Exclusive Attributes" by chad</title>
      <description>&lt;p&gt;Hi Bob &amp;#8211; just found your blog. you should post more often. there are a number of places i could have used this validation block feature. was this new in rails 1.2.3?&lt;/p&gt;</description>
      <pubDate>Wed, 19 Sep 2007 23:43:03 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:c77925b3-b712-4c0a-bd01-cbadadec9dde</guid>
      <link>http://www.robertshowalter.com/articles/2007/09/16/validating-mutually-exclusive-attributes#comment-919</link>
    </item>
  </channel>
</rss>
