<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>The BitMacro Blog - Home</title>
  <id>tag:blog.bitmacro.com,2008:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://blog.bitmacro.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blog.bitmacro.com/" rel="alternate" type="text/html"/>
  <updated>2008-04-16T05:08:45Z</updated>
  <entry xml:base="http://blog.bitmacro.com/">
    <author>
      <name>mlins</name>
    </author>
    <id>tag:blog.bitmacro.com,2007-08-21:74</id>
    <published>2007-08-21T07:16:00Z</published>
    <updated>2008-04-16T05:08:45Z</updated>
    <category term="Rails"/>
    <category term="Ruby"/>
    <link href="http://blog.bitmacro.com/2007/8/21/dissecting-rails-validations-part-ii" rel="alternate" type="text/html"/>
    <title>Dissecting Rails Validations - Part II</title>
<content type="html">
            &lt;h3&gt;The loading of the built-in validators&lt;/h3&gt;
&lt;p&gt;
Well, it looks as if my posts will be irrespective of the actual chronology of events involved in validation. At least from a Rails start-to-finish call stack perspective. This post will venture back before those events discussed in &lt;a href=&quot;http://blog.webinforem.com/2007/08/13/dissecting-rails-validations-part-i/&quot;&gt;Part I&lt;/a&gt;. The reason being, I forgot to mention how the Rails built-in validators are loaded and executed.&lt;/p&gt;
&lt;p&gt;When your model's class definition is encountered(during initialization), all of the method calls to the built-in validators are ran. Let's say we have a model that looks like this:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Supplier&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validates_uniqueness_of &lt;span class=&quot;sy&quot;&gt;:name&lt;/span&gt;   &lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;When &lt;b&gt;#validates_uniqueness_of&lt;/b&gt; is called, it jumps to &lt;b&gt;ActiveRecord::Validations::ClassMethods&lt;/b&gt;, which was mixed in with &lt;b&gt;ActiveRecord::Base&lt;/b&gt; during initilization earlier. We're not going to look at this method in whole because it's too long. The important part is that it makes use of &lt;b&gt;#validates_each&lt;/b&gt;. I'd like to talk about &lt;b&gt;#validates_each&lt;/b&gt; because it is the heart of almost all the built-in validators(some can't use it). Here it is:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validates_each&lt;/span&gt;(*attrs)&lt;tt&gt;
&lt;/tt&gt;  options = attrs.last.is_a?(&lt;span class=&quot;co&quot;&gt;Hash&lt;/span&gt;) ? attrs.pop.symbolize_keys : {}&lt;tt&gt;
&lt;/tt&gt;  attrs   = attrs.flatten&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;# Declare the validation.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  send(validation_method(options[&lt;span class=&quot;sy&quot;&gt;:on&lt;/span&gt;] || &lt;span class=&quot;sy&quot;&gt;:save&lt;/span&gt;)) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |record|&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;# Don't validate when there is an :if condition and that condition is false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;unless&lt;/span&gt; options[&lt;span class=&quot;sy&quot;&gt;:if&lt;/span&gt;] &amp;amp;&amp;amp; !evaluate_condition(options[&lt;span class=&quot;sy&quot;&gt;:if&lt;/span&gt;], record)&lt;tt&gt;
&lt;/tt&gt;      attrs.each &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |attr|&lt;tt&gt;
&lt;/tt&gt;        value = record.send(attr)&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;r&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; value.nil? &amp;amp;&amp;amp; options[&lt;span class=&quot;sy&quot;&gt;:allow_nil&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;r&quot;&gt;yield&lt;/span&gt; record, attr, value&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;After the first couple of lines you see this:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;send(validation_method(options[&lt;span class=&quot;sy&quot;&gt;:on&lt;/span&gt;] || &lt;span class=&quot;sy&quot;&gt;:save&lt;/span&gt;)) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |record|&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This line of code is using the Ruby &lt;b&gt;#send&lt;/b&gt; method to make a dynamic call to whatever &lt;b&gt;#validation_method&lt;/b&gt; returns. Let's look at it:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validation_method&lt;/span&gt;(on)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;case&lt;/span&gt; on&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;sy&quot;&gt;:save&lt;/span&gt;   &lt;span class=&quot;r&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;sy&quot;&gt;:validate&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;sy&quot;&gt;:create&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;sy&quot;&gt;:validate_on_create&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;sy&quot;&gt;:update&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;sy&quot;&gt;:validate_on_update&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;When you declare your validation in your model, &lt;b&gt;:on&lt;/b&gt; is an optional parameter. So, if we only wanted to run our validation on only the creation of records, we could do this:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Supplier&lt;/span&gt; &amp;amp;gt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validates_uniqueness_of &lt;span class=&quot;sy&quot;&gt;:name&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:on&lt;/span&gt; =&amp;gt; &lt;span class=&quot;sy&quot;&gt;:create&lt;/span&gt;   &lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The &lt;b&gt;#validation_method&lt;/b&gt; method will tell the &lt;b&gt;#send&lt;/b&gt; method back in &lt;b&gt;#validates_each&lt;/b&gt; where to declare the validator. Assuming we pass don't pass anything for the &lt;b&gt;:on&lt;/b&gt; parameter it'll be declared by &lt;b&gt;#validate&lt;/b&gt;(both create and update). Don't get these methods confused with low-level &lt;b&gt;#validate&lt;/b&gt;, &lt;b&gt;#validate_on_create&lt;/b&gt; and &lt;b&gt;#validate_on_update&lt;/b&gt; of which you can override in your models. These are defined outside of &lt;b&gt;Validations::ClassMethods&lt;/b&gt; and they have a different amount of parameters. Lets look at &lt;b&gt;Validations::ClassMethods#validate&lt;/b&gt;:
&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;validate&lt;/span&gt;(*methods, &amp;amp;block)&lt;tt&gt;
&lt;/tt&gt;  methods &amp;lt;&amp;lt; block &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; block_given?&lt;tt&gt;
&lt;/tt&gt;  write_inheritable_set(&lt;span class=&quot;sy&quot;&gt;:validate&lt;/span&gt;, methods)&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Validators can be methods, classes or blocks. This method will handle whatever you throw at it and toss it onto the array of validations to be ran whenever &lt;b&gt;#valid?&lt;/b&gt; is called. It's using a method called &lt;b&gt;#write_inheritable_set&lt;/b&gt; to store the array (read more about it in the &lt;a href=&quot;http://dev.rubyonrails.org/browser/tags/rel_1-2-3/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb&quot;&gt;inheritable_attributes.rb&lt;/a&gt; file).&lt;/p&gt;
&lt;p&gt;Now, if you remember correctly from &lt;a href=&quot;http://blog.webinforem.com/2007/08/13/dissecting-rails-validations-part-i/&quot;&gt;Part I&lt;/a&gt; the &lt;b&gt;ActiveRecord::Base#save&lt;/b&gt; call is actually aliased to &lt;b&gt;ActiveRecord::Validations#save_with_validation&lt;/b&gt;. This method makes a call to &lt;b&gt;ActiveRecord::Validations#valid?&lt;/b&gt;. Let's dig into it:
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;valid?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  errors.clear&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  run_validations(&lt;span class=&quot;sy&quot;&gt;:validate&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  validate&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; new_record?&lt;tt&gt;
&lt;/tt&gt;    run_validations(&lt;span class=&quot;sy&quot;&gt;:validate_on_create&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    validate_on_create&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    run_validations(&lt;span class=&quot;sy&quot;&gt;:validate_on_update&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    validate_on_update&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  errors.empty?&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;First, it clears the errors object. The errors object is defined by the &lt;b&gt;ActiveRecord::Errors&lt;/b&gt; class, which mixes in Enumerable. You can add errors with &lt;b&gt;#add&lt;/b&gt; and clear them with &lt;b&gt;#clear&lt;/b&gt; etc. Anytime a validator encounters a problem with your model it adds an error. Next, &lt;b&gt;#valid?&lt;/b&gt; calls &lt;b&gt;#run_validations&lt;/b&gt; with &lt;b&gt;:validate&lt;/b&gt; as a parameter(validation_method). Remember, these are validations that are called on both create and update. Continuing, it determines whether the record is new, it calls &lt;b&gt;#run_validations&lt;/b&gt; again with the appropriate parameter(validation_method). Lastly, it returns the result of the expression &lt;b&gt;errors.empty?&lt;/b&gt;. So, if any problems occurred during &lt;b&gt;#run_validations&lt;/b&gt;, then the validator would have added an error to the enumerable causing &lt;b&gt;#valid?&lt;/b&gt; to return &lt;b&gt;false&lt;/b&gt;. Let's look at &lt;b&gt;#run_validations&lt;/b&gt;:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;run_validations&lt;/span&gt;(validation_method)&lt;tt&gt;
&lt;/tt&gt;  validations = &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.read_inheritable_attribute(validation_method.to_sym)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; validations.nil? &lt;span class=&quot;r&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validations.each &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |validation|&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; validation.is_a?(&lt;span class=&quot;co&quot;&gt;Symbol&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.send(validation)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;elsif&lt;/span&gt; validation.is_a?(&lt;span class=&quot;co&quot;&gt;String&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      eval(validation, binding)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;elsif&lt;/span&gt; validation_block?(validation)&lt;tt&gt;
&lt;/tt&gt;      validation.call(&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;elsif&lt;/span&gt; validation_class?(validation, validation_method)&lt;tt&gt;
&lt;/tt&gt;      validation.send(validation_method, &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      raise(&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;co&quot;&gt;ActiveRecordError&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Validations need to be either a symbol, string (to be eval'ed), proc/method, or &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;         &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class implementing a static validation method&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      )&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
It grabs all the validations based on the &lt;b&gt;validation_method&lt;/b&gt; passed using the &lt;b&gt;#read_inheritable_attribute&lt;/b&gt; (look in the &lt;a href=&quot;http://dev.rubyonrails.org/browser/tags/rel_1-2-3/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb&quot;&gt;inheritable_attributes.rb&lt;/a&gt; file to find out why this is used). Next, it iterates through each of the validations. It does a check to see if the validation is a method, class or a block and executes it appropriately. Remember, if these validations encounter problems with the model data, they'll add an error onto the &lt;b&gt;@errors&lt;/b&gt; enumerable causing &lt;b&gt;#valid?&lt;/b&gt; to return &lt;b&gt;false&lt;/b&gt;. Let's tie it all together with a review of the &lt;b&gt;#save_with_validation&lt;/b&gt; method:
&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;save_with_validation&lt;/span&gt;(perform_validation = &lt;span class=&quot;pc&quot;&gt;true&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; perform_validation &amp;amp;&amp;amp; valid? || !perform_validation&lt;tt&gt;
&lt;/tt&gt;    save_without_validation&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;If &lt;b&gt;#valid?&lt;/b&gt; returns &lt;b&gt;true&lt;/b&gt;(and you didn't pass &lt;b&gt;false&lt;/b&gt; to &lt;b&gt;#save&lt;/b&gt;), then &lt;b&gt;#save_with_validation&lt;/b&gt; makes a call to &lt;b&gt;#save_without_validation&lt;/b&gt;, which is actually aliased back to &lt;b&gt;ActiveRecord::Base#save&lt;/b&gt; thus completing our save. Remember, &lt;b&gt;ActiveRecord::Base#save&lt;/b&gt; is actually aliased to &lt;b&gt;#save_with_validation&lt;/b&gt; so that validations can happen. Confused? Well, this is done with &lt;a href=&quot;http://blog.webinforem.com/2007/08/16/cant-find-that-rails-method-alias_method_chain/&quot;&gt;#alias_method_chain&lt;/a&gt;. Also, you may need to review &lt;a href=&quot;http://blog.webinforem.com/2007/08/13/dissecting-rails-validations-part-i/&quot;&gt;Part I&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That should do it for another part to this series. If I feel the need to write Part III, we'll probably dive into what each of the built-in validators is actually doing.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.bitmacro.com/">
    <author>
      <name>mlins</name>
    </author>
    <id>tag:blog.bitmacro.com,2007-08-16:64</id>
    <published>2007-08-16T08:46:00Z</published>
    <updated>2008-04-16T20:02:05Z</updated>
    <category term="Rails"/>
    <category term="Ruby"/>
    <link href="http://blog.bitmacro.com/2007/8/16/cant-find-that-rails-method-alias_method_chain" rel="alternate" type="text/html"/>
    <title>Can't find that Rails Method? (alias_method_chain)</title>
<content type="html">
            &lt;p&gt;I've been digging through the core more and more. One thing that still throws me off once in a while are method declarations that I can't seem to find. Naturally, I first do a search for the method name in a bunch of files. When it doesn't show up, I become frustrated because even if it was aliased, it should still come up in search. Well, if that's the case, look no further than a call to &lt;b&gt;#alias_method_chain&lt;/b&gt;(usually). Even though I was aware of this method(&lt;a href=&quot;http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain&quot;&gt;it's nothing new&lt;/a&gt;), it still throws me off. I just need to remember anytime I see &quot;with&quot; or &quot;without&quot; in the method name, I should probably search for a call to &lt;b&gt;#alias_method_chain&lt;/b&gt;.
&lt;/p&gt;
&lt;p&gt;
For those of you not aware of what it is, here is the code(aliasing.rb):
&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;alias_method_chain&lt;/span&gt;(target, feature)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;# Strip out punctuation on predicates or bang methods since&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;# e.g. target?_without_feature is not a valid method name.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  aliased_target, punctuation = target.to_s.sub(&lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;([?!=])$&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;), &lt;span class=&quot;gv&quot;&gt;$1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;yield&lt;/span&gt;(aliased_target, punctuation) &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; block_given?&lt;tt&gt;
&lt;/tt&gt;  alias_method &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;aliased_target&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_without_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;feature&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;punctuation&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, target&lt;tt&gt;
&lt;/tt&gt;  alias_method target, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;aliased_target&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_with_&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;feature&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;punctuation&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;It is used to DRY up the common aliasing pattern of:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;alias_method &lt;span class=&quot;sy&quot;&gt;:foo_without_feature&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:foo&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;alias_method &lt;span class=&quot;sy&quot;&gt;:foo&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:foo_with_feature&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
This is used a lot in the Rails core. It is nice, but when you're not aware of it, it can certainly wear on you when trying to understand some code. I know it's a method that has been talked about plenty, but it's one of those things that is hard to search for when you're actually trying to solve the mystery it created.
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.bitmacro.com/">
    <author>
      <name>mlins</name>
    </author>
    <id>tag:blog.bitmacro.com,2007-08-13:73</id>
    <published>2007-08-13T21:11:00Z</published>
    <updated>2008-04-16T05:07:43Z</updated>
    <category term="Rails"/>
    <category term="Ruby"/>
    <link href="http://blog.bitmacro.com/2007/8/13/dissecting-rails-validations-part-i" rel="alternate" type="text/html"/>
    <title>Dissecting Rails Validations - Part I </title>
<content type="html">
            &lt;h3&gt;The road from save to validation.&lt;/h3&gt;
&lt;p&gt;Rails validations seem simple on the outside, but have you ever taken the time to understand what's really going on? What actually happens when you do &lt;b&gt;model.save&lt;/b&gt;? I ran into a problem one day and I decided to take a gander and figure out how it all works. It was a little difficult. The Rails core can be very daunting. With the mix-ins, aliases and the enormity of the ActiveRecord code base, one could spend hours trying to figure it out. Well, I did and I'm going to try to explain it.&lt;/p&gt;
&lt;p&gt;
To start, I have my Rails application froze to 1.2.3 and I can easily browse the code by looking in my &lt;i&gt;vendors/rails/&lt;/i&gt; directory(you could check it out of SVN if you desire, to follow along). All the files I mention will be relative to that path. I began my journey in the &lt;i&gt;activerecord/validations.rb&lt;/i&gt; file. It contains a contains two ActiveRecord classes: &lt;b&gt;ActiveRecord::Errors&lt;/b&gt; and &lt;b&gt;ActiveRecord:RecordInvalid&lt;/b&gt; and a module: &lt;b&gt;Validations&lt;/b&gt;, which contains another module: &lt;b&gt;Validations::ClassMethods&lt;/b&gt;. Well, this file gave me a nice idea of how things like &lt;b&gt;validates_presence_of&lt;/b&gt; works(which I'll explain later), but I wanted to know more. Specifically, during the save process, when do validations get called and from where?&lt;/p&gt;
&lt;p&gt; 
Well, I scanned right over some clues in &lt;i&gt;activerecord/validations.rb&lt;/i&gt; and hastily decided to go right into the heart of ActiveRecord: &lt;b&gt;ActiveRecord::Base&lt;/b&gt; in &lt;i&gt;activerecord/base.rb&lt;/i&gt;. I was puzzled when I found the &lt;b&gt;#save&lt;/b&gt; and &lt;b&gt;#save!&lt;/b&gt; methods.&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# * No record exists: Creates a new record with values &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#   matching those of the object attributes.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# * A record does exist: Updates the record with &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#   values matching those of the object attributes.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;save&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  create_or_update&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# Attempts to save the record, but instead of just returning false if it couldn't happen, &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# it raises a RecordNotSaved exception&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;save!&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  create_or_update || raise(&lt;span class=&quot;co&quot;&gt;RecordNotSaved&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
 
&lt;p&gt;Naturally, I moved on to &lt;b&gt;#create_or_update&lt;/b&gt;, to find:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;create_or_update&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  raise &lt;span class=&quot;co&quot;&gt;ReadOnlyRecord&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; readonly?&lt;tt&gt;
&lt;/tt&gt;  result = new_record? ? create : update&lt;tt&gt;
&lt;/tt&gt;  result != &lt;span class=&quot;pc&quot;&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
Getting closer, but not quite what I'm looking for. This method checks and raises an exception if the record is read-only. Then it determines if the record is new and calls the appropriate method for a create or update.&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# Updates the associated record with values matching those of the instance attributes.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# Returns the number of affected rows.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;update&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  connection.update(&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;UPDATE &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.table_name&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SET &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;quoted_comma_pair_list(connection, attributes_with_quotes(&lt;span class=&quot;pc&quot;&gt;false&lt;/span&gt;))&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;WHERE &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;connection.quote_column_name(&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.primary_key)&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; = &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;quote_value(id)&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.name&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; Update&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  )&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# Creates a record with values matching those of the instance attributes&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# and returns its id.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;create&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.id.nil? &amp;amp;&amp;amp; connection.prefetch_primary_key?(&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.table_name)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.id = connection.next_sequence_value(&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.sequence_name)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.id = connection.insert(&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;INSERT INTO &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.table_name&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;quoted_column_names.join(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;VALUES(&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;attributes_with_quotes.values.join(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.name&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; Create&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.primary_key, &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.id, &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.class.sequence_name&lt;tt&gt;
&lt;/tt&gt;  )&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;iv&quot;&gt;@new_record&lt;/span&gt; = &lt;span class=&quot;pc&quot;&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  id&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
Where does validation come into play? We're already building SQL? Well this stumped me for about 10 seconds. Then I realized somewhere they must be mixing in the validation functionality.  Logically, I headed back to &lt;i&gt;activerecord/validations.rb&lt;/i&gt; to find what I overlooked:&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.included(base) &lt;span class=&quot;c&quot;&gt;# :nodoc:&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  base.extend &lt;span class=&quot;co&quot;&gt;ClassMethods&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  base.class_eval &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method_chain &lt;span class=&quot;sy&quot;&gt;:save&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:validation&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method_chain &lt;span class=&quot;sy&quot;&gt;:save!&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:validation&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    alias_method_chain &lt;span class=&quot;sy&quot;&gt;:update_attribute&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:validation_skipping&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
This code is aliasing the &lt;b&gt;Base#save&lt;/b&gt; method to &lt;b&gt;Validations#save_with_validation&lt;/b&gt;, which is mixed in just prior. To do so, it uses a built-in rails convenience method: &lt;b&gt;#alias_method_chain&lt;/b&gt;. This happens when the module is loaded by using &lt;b&gt;self.included&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;
I really enjoy the design of ActiveRecord. It is totally usable outside of Rails. Not only that, if you don't need validation then you simply don't load &lt;i&gt;activerecord/validation.rb&lt;/i&gt;(Rails does this by default during initialization). But, just because you load the Validations module, doesn't mean you actually need to validate on save. As seen in the overridden methods below, you can simply pass false as a parameter.&lt;/p&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# The validation process on save can be skipped by passing false. The regular Base#save method&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# is replaced with this when the validations module is mixed in, which it is by default.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;save_with_validation&lt;/span&gt;(perform_validation = &lt;span class=&quot;pc&quot;&gt;true&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; perform_validation &amp;amp;&amp;amp; valid? || !perform_validation&lt;tt&gt;
&lt;/tt&gt;    save_without_validation&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# Attempts to save the record just like Base#save but will raise a RecordInvalid exception &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# instead of returning false if the record is not valid.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;save_with_validation!&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; valid?&lt;tt&gt;
&lt;/tt&gt;    save_without_validation!&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    raise &lt;span class=&quot;co&quot;&gt;RecordInvalid&lt;/span&gt;.new(&lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;
Well I think this is a good place to stop for Part I of this series. In the next post we will dig in to the actual validation process.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.bitmacro.com/">
    <author>
      <name>mlins</name>
    </author>
    <id>tag:blog.bitmacro.com,2007-07-30:72</id>
    <published>2007-07-30T00:00:00Z</published>
    <updated>2008-04-16T05:11:18Z</updated>
    <category term="BDD"/>
    <category term="Rails"/>
    <category term="rSpec"/>
    <link href="http://blog.bitmacro.com/2007/7/30/lose-the-fixtures-with-rspec" rel="alternate" type="text/html"/>
    <title>Lose the fixtures with rSpec</title>
<content type="html">
            &lt;p&gt;rSpec is all about writing easy to read, self-explanatory specs (tests to you TDDr's).  It's tempting to want to use fixtures or even come up with a clever way to provide sample data for testing models. I'll demonstrate, what I consider to be the most beautiful way to write specs.  Some of my influences have been the &lt;a href=&quot;http://rubyforge.org/mailman/listinfo/rspec-users&quot;&gt;rSpec Mailing list&lt;/a&gt; and the &lt;a href=&quot;http://peepmacro:code.com/products/rspec-basics&quot;&gt;PeepCode Screencast&lt;/a&gt;.  I'll warn you brilliant ruby programmers: this is by no means efficient, DRY code.  It is code that any stranger could come along and figure out exactly what the original developer was trying to accomplish.&lt;/p&gt;

&lt;p&gt;Assume we have a simple Model like this:&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Post&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  validates_presence_of &lt;span class=&quot;sy&quot;&gt;:title&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validates_length_of &lt;span class=&quot;sy&quot;&gt;:title&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:minimum&lt;/span&gt; =&amp;gt; &lt;span class=&quot;i&quot;&gt;2&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;First we'll need the help of a couple of additional methods in Hash.  Add this to your spec_helper.rb in the root of your /spec directory.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# Taken from &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;# http://wincent.com/knowledge-base/Fixtures_considered_harmful%3F&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Hash&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;# for excluding keys&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;except&lt;/span&gt;(*exclusions)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.reject { |key, value| exclusions.include? key.to_sym }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;c&quot;&gt;# for overriding keys&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;with&lt;/span&gt;(overrides = {})&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.merge overrides&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;These two methods with allow us to create a &quot;valid_attributes&quot; Hash and then tweak it later on.  We're going to create a helper module at the top of the spec.  This example is from one of my specs for a model: Post.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;require &lt;span class=&quot;co&quot;&gt;File&lt;/span&gt;.dirname(&lt;span class=&quot;pc&quot;&gt;__FILE__&lt;/span&gt;) + &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;/../spec_helper&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;PostSpecHelper&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;valid_post_attributes&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    {&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;sy&quot;&gt;:title&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;rSpec is Great&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;sy&quot;&gt;:body&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;rSpec is a fun way to write documentation &lt;tt&gt;
&lt;/tt&gt;        and test your application at the same time&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Now we have some nice sample data.  We can use this helper(don't forget to include it) in the before(setup) block of each of our describe blocks.  Let start with a simple valid Post.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;describe &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class=&quot;co&quot;&gt;PostSpecHelper&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  before(&lt;span class=&quot;sy&quot;&gt;:each&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt; = &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt;.attributes = valid_post_attributes&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt;.should be_valid&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Great. Now let's use the add Hash#with to test one of our validations.&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;describe &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with a title that is 1 character long&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class=&quot;co&quot;&gt;PostSpecHelper&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  before(&lt;span class=&quot;sy&quot;&gt;:each&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt; = &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt;.attributes = valid_post_attributes.with(&lt;span class=&quot;sy&quot;&gt;:title&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt;.should_not be_valid&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;should have an error on title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt;.should have(&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;).error_on(&lt;span class=&quot;sy&quot;&gt;:title&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Now, we'll use the Hash#except to test another validation&lt;/p&gt;

&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;describe &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with a blank title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class=&quot;co&quot;&gt;PostSpecHelper&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  before(&lt;span class=&quot;sy&quot;&gt;:each&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt; = &lt;span class=&quot;co&quot;&gt;Post&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt;.attributes = valid_post_attributes.except(&lt;span class=&quot;sy&quot;&gt;:title&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt;.should_not be_valid&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;should have an error on title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;iv&quot;&gt;@post&lt;/span&gt;.should have(&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;).error_on(&lt;span class=&quot;sy&quot;&gt;:title&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;There you have it, an easy to read spec. Any developer could come along and figure out exactly what I was testing. The sample data is provided in the top of every spec.  I don't have to go searching through fixtures to figure out why this test failed.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.bitmacro.com/">
    <author>
      <name>mlins</name>
    </author>
    <id>tag:blog.bitmacro.com,2007-05-16:60</id>
    <published>2007-05-16T23:01:00Z</published>
    <updated>2008-04-16T17:26:51Z</updated>
    <category term="Rails"/>
    <link href="http://blog.bitmacro.com/2007/5/16/railsconf-2007" rel="alternate" type="text/html"/>
    <title>RailsConf 2007</title>
<content type="html">
            &lt;p&gt;I've arrived in Portland, OR for &lt;a href=&quot;http://conferences.oreillynet.com/rails/&quot;&gt;RailsConf 2007&lt;/a&gt;.  I'm pretty excited, it should be a great experience.&lt;/p&gt;

&lt;p&gt;I came out early for some of the sessions(tutorials).  I'm attending the &lt;a href=&quot;http://jruby.macro:codehaus.org/&quot;&gt;jRuby&lt;/a&gt; and the &lt;a href=&quot;http://rubyforge.org/projects/capistrano/&quot;&gt;Capistrano&lt;/a&gt; session.  I'm really looking forward to the jRuby session, I've only read about it and have yet to use it.  I really like the idea of being able to throw a rails app into a war file and deploy it in a web container.&lt;/p&gt;

&lt;p&gt;I'm going to try to post many updates about the conference.  I brought my new camera, but unfortunately I forgot the charger and I only have about a 1/8 bar left.  We'll see how  many I can snap.&lt;/p&gt;

&lt;p&gt;I'll post tomorrow in detail about the sessions.&lt;/p&gt;
          </content>  </entry>
</feed>
