<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Michael Schuerig &#187; Ruby</title>
	<atom:link href="http://www.schuerig.de/michael/blog/index.php/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.schuerig.de/michael/blog</link>
	<description>Sentenced to making sense</description>
	<lastBuildDate>Tue, 06 Sep 2011 07:21:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Creative Associations</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2009/05/29/creative-associations/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2009/05/29/creative-associations/#comments</comments>
		<pubDate>Fri, 29 May 2009 14:01:58 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.schuerig.de/michael/blog/?p=62</guid>
		<description><![CDATA[A presentation I held on May 28 at Düsseldorf on Rails about interesting and useful things you can do with ActiveRecord, SQL, and a smart database. german english .]]></description>
			<content:encoded><![CDATA[<p>A presentation I held on May 28 at <a href="http://groups.google.de/group/duesseldorf-on-rails">Düsseldorf on Rails</a> about interesting and useful things you can do with <tt>ActiveRecord</tt>, <tt>SQL</tt>, and a smart database.</p>
<ul>
<li><a href="http://www.schuerig.de/michael/pres/kreative-assoziationen/index.html">german</a></li>
<li><a href="http://www.schuerig.de/michael/pres/kreative-assoziationen/index.html.en">english</a></li>
</ul>
<p>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2009/05/29/creative-associations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby as a language for Rails views</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2009/04/02/ruby-views/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2009/04/02/ruby-views/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 22:55:31 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.schuerig.de/michael/blog/?p=57</guid>
		<description><![CDATA[Didn&#8217;t you always want to write your Rails views as plain Ruby objects? &#8212; &#8220;What?&#8221;, I hear you say. No, I haven&#8217;t lost my mind and the idea is quite sensible (or so I hope), once you add the restriction that it is JSON-formatted data that you want to return. Say you need to set [...]]]></description>
			<content:encoded><![CDATA[<p>Didn&#8217;t you always want to write your Rails views as plain Ruby objects? &#8212; <em>&#8220;What?&#8221;</em>, I hear you say. No, I haven&#8217;t lost my mind and the idea is quite sensible (or so I hope), once you add the restriction that it is JSON-formatted data that you want to return.</p>
<p>Say you need to set up some hashes or arrays for rendering to JSON. This is best done in Ruby and it is clearly a view concern. So let&#8217;s do it in the views. Like this:</p>
<p><code>
<pre>
  # app/controllers/movies_controller.rb
  def index
    respond_to do |format|
      format.json do
        @movies = Movie.all
        @count = Movie.count
        render :template =&gt; 'movies/index.json.rb'
      end
    end
  end
</pre>
<p></code></p>
<p><code>
<pre>
  # app/views/movies/index.json.rb
  {
    :identifier =&gt; Movie.primary_key,
    :totalCount =&gt; @count,
    # render @movies does not work as it insists on returning a string
    :items =&gt; @movies.map { |m| render(m) }
  }
</pre>
<p></code></p>
<p><code>
<pre>
  # app/views/movies/_movie.json.rb
  {
    :id =&gt; movie.to_param,
    :title =&gt; movie.title,
    :releaseDate =&gt; movie.release_date
  }
</pre>
<p></code></p>
<h2>Getting it</h2>
<ul>
<li><a href="http://github.com/mschuerig/ruby_template_handler">github</a></li>
<li>$ sudo gem install mschuerig-ruby_template_handler</li>
</ul>
<h2>Let your Rails app know about it</h2>
<p>In the appropriate place in <code>config/environment.rb</code> add</p>
<p><code>
<pre>
config.gem "mschuerig-ruby_template_handler", :lib =&gt; 'ruby_template_handler'
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2009/04/02/ruby-views/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gem: Updated Bash completion</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2007/12/22/gem-bash-completion-10/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2007/12/22/gem-bash-completion-10/#comments</comments>
		<pubDate>Sat, 22 Dec 2007 09:37:27 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/index.php/2007/12/22/gem-bash-completion-10/</guid>
		<description><![CDATA[Victor Serbin sent me a version of the completion updated for Gem 1.0.1. You can get it here. Apparently, Ubuntu and Debian have begun to bundle this file with their rubygems packages. Great!]]></description>
			<content:encoded><![CDATA[<p>Victor Serbin sent me a version of the completion updated for Gem 1.0.1. You can get it <a href="http://www.schuerig.de/michael/ruby/gem.bash_completion">here</a>.</p>
<p>Apparently, Ubuntu and Debian have begun to bundle this file with their rubygems packages. Great!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2007/12/22/gem-bash-completion-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bash Completion for the gem Command</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2007/02/24/gem-bash-completion/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2007/02/24/gem-bash-completion/#comments</comments>
		<pubDate>Sat, 24 Feb 2007 01:41:39 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/index.php/2007/02/24/gem-bash-completion/</guid>
		<description><![CDATA[The gem command is the command line user interface to the RubyGems system for managing Ruby packages. This command has a few sub-commands itself and a long list of options that differ per sub-command. Remembering and typing them can be tedious, but thankfully, if you are using the bash command shell, it can help with [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://rubygems.org/read/book/2"><code>gem</code></a> command is the command line user interface to the <a href="http://rubygems.org/">RubyGems</a> system for managing Ruby packages.</p>
<p>This command has a few sub-commands itself and a long list of options that differ per sub-command. Remembering and typing them can be tedious, but thankfully, if you are using the <code>bash</code> command shell, it can help with this task. It only has to be told <em>how</em>.</p>
<p>I&#8217;ve packaged the <em>how</em> in <a href="http://www.schuerig.de/michael/ruby/gem.bash_completion.old">this file</a>. Copy it to <code>/etc/bash_completion.d</code> and hope that your <code>bash</code> installation picks it up the next time you start a shell.</p>
<p>On Debian/Linux system that&#8217;s just how it works. If this does not work on your particular version of Linux or Unix, you&#8217;ll have to look up how completions are handled on your system.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2007/02/24/gem-bash-completion/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Popular Requests</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2007/02/14/popular-requests/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2007/02/14/popular-requests/#comments</comments>
		<pubDate>Tue, 13 Feb 2007 23:29:40 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/index.php/2007/02/14/popular-requests/</guid>
		<description><![CDATA[It was late last night. And the night before, I admit it. I also admit that I don&#8217;t know much about what Web 2.0 is all about, but there are two things that I do know: rounded corners are involved and, of course tags and tag clouds. Tagging is work, therefore ipso facto to be [...]]]></description>
			<content:encoded><![CDATA[<p>It was late last night. And the night before, I admit it. I also admit that I don&#8217;t know much about what <em>Web 2.0</em> is all about, but there are two things that I do know: rounded corners are involved and, of course tags and tag clouds.</p>
<p>Tagging is work, therefore <a href="http://en.wikipedia.org/wiki/Ipso_facto"><em>ipso facto</em></a> to be avoided, better still: automated.</p>
<p>Let&#8217;s say you want to show people which part of your site are popular. How about a tag cloud of the most requested locations? Well, the first thing to do would be to collect which requests are happening at all. Also, you&#8217;d need to attach a sensible, displayable title to the raw request. For the sake of this little demonstration, I&#8217;m going to assume that in your template &#8212; <code>list.rhtml</code>, <code>edit.rhtml</code>, and brethren &#8212; you have an instance variable <code>@title</code>. It could be either defined in the template itself or transplanted there from its controller, it doesn&#8217;t matter.</p>
<p>Given all this, you could hypothetically write code like this.</p>
<p><code>
<pre>
class ApplicationController < ActionController::Base
  collect_popular_requests :max_age =&gt; 7.days, :max_count =&gt; 10000,
    :title =&gt; proc { |controller| controller.response.template.instance_variable_get(:@title) }
</pre>
<p></code></p>
<p>Therein further assuming that at most the 10000 most recent requests are kept if they are no older than 7 days. Now that we have hypothetically collected the data to base our tag cloud on, we have to display it somehow. Again, let's assume it could be done with a route like this</p>
<p><code>
<pre>
map.popular '/', :controller => 'most_popular', :action => 'index'
</pre>
<p></code></p>
<p>a controller like that</p>
<p><code>
<pre>
class MostPopularController < ApplicationController
  helper BoilerPlate::PopularRequestsHelper
  collect_popular_requests :\off # Ignore this place

  def index
    @popular_requests = popular_requests_list.most_popular(30)
  end
end
</pre>
<p></code></p>
<p>and for good measure a view (<code>index.rhtml</code>)</p>
<p><code>
<pre>
&lt;ul class="tagcloud"&gt;
&lt;% alpha_reqs = @popular_requests.sort_by(&#038;:title) -%&gt;
&lt;% alpha_reqs.each do |req| -%&gt;
  &lt;%= popular_request_tag(req, :wrap =&gt; 'li', :min_size =&gt; 30, :max_size =&gt; 400) %&gt;
&lt;% end -%&gt;
&lt;/ul&gt;
</pre>
<p></code></p>
<p>and some CSS for good style</p>
<p><code>
<pre>
.tagcloud {
  text-align: center;
  width: 70%;
}
.tagcloud li {
  display: inline-block;
  display: -moz-inline-box;
  white-space: nowrap;
  vertical-align: middle;
  line-height: 1.2em;
  padding: 0 0.2em;
}
</pre>
<p></code></p>
<p>Well, if you've made it this far, you might even consider doing all of this for real. For a good start, I suggest you download <a href="http://schuerig.de/michael/blog/wp-content/uploads/2007/02/popular_requests.tar.gz">this Rails plugin</a>, install it, create a database table with</p>
<p><code>
<pre>
$ script/generate popular_requests AddPopularRequests
$ rake db:migrate
</pre>
<p></code></p>
<p>and start playing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2007/02/14/popular-requests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Self-conscious Decoration</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2007/02/12/self-conscious-decoration/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2007/02/12/self-conscious-decoration/#comments</comments>
		<pubDate>Mon, 12 Feb 2007 22:27:16 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/index.php/2007/02/12/self-conscious-decoration/</guid>
		<description><![CDATA[Variations on the Decorator Design Pattern in Ruby have already been discussed in several places. For my special purpose, none of these approaches works. The common problem with a decorator based on delegation is the lost sense of self. Method calls of the decorated object to itself are not routed through the decorator, therefore remain [...]]]></description>
			<content:encoded><![CDATA[<p>Variations on the Decorator Design Pattern in Ruby have already been discussed <a href="http://cwilliams.textdriven.com/articles/2006/10/27/patterns-in-ruby-template-method">in</a> <a href="http://cwilliams.textdriven.com/articles/2006/12/26/patterns-in-ruby-decorator-revisited">several</a> <a href="http://www.lukeredpath.co.uk/2006/9/6/decorator-pattern-with-ruby-in-8-lines">places</a>. For my special purpose, none of these approaches works.</p>
<p>The common problem with a decorator based on <a href="http://javalab.cs.uni-bonn.de/research/darwin/delegation.html">delegation</a> is the lost sense of self. Method calls of the decorated object to itself are not routed through the decorator, therefore remain woefully undecorated.</p>
<p>The Ruby idiom of aliasing and redefining methods, in effect adding around advice, is possible, when the decoration applies to all uses of the &#8220;core&#8221; class. It is not suitable when you need decorated as well as undecorated variants.</p>
<p>There&#8217;s an almost classical: Just derive a subclass from the &#8220;core&#8221; class and add the decoration in there. Doing this explicitly is tedious, ugly, and multiplies classes <em>semper necessitatem</em>. Luckily, for us and poor, overquoted Father Ockham, Ruby is a highly dynamic language where things are possible that users of other languages can only dream of (longingly or in nightmares, that&#8217;s quite a different issue).</p>
<p>So, without further ado, here&#8217;s a simple demonstration of the technique.</p>
<p><code>
<pre>
class Core
  def m1
    puts "Core#m1"
  end

  def m2
    puts "Core#m2"
    m3
  end

  def m3
    puts "Core#m3"
  end

  def m4
    puts "Core#m4"
  end
end

class Decorator
  class &lt;&lt; self
    def new(*args)
      decorate(Core).new(*args)
    end

    private
    def decorate(klass)
      decorated_class = Class.new(klass)
      decorated_class.send(:include, Decoration)
      decorated_class
    end
  end

  module Decoration
    def m1
      puts "Decorator#m1"
      super
    end

    def m2
      puts "Decorator#m2"
      super
    end
    def m3
      puts "Decorator#m3"
      super
    end
  end
end
</pre>
<p></code></p>
<p>With that under under our collective belt, here&#8217;s the case that motivated my attempt at self-conscious delegation. In a Rails application, I have several layers of <code>FormBuilder</code>s. At the base, derived from <code>ActionView::Helpers::FormBuilder</code> is a form builder that provides <em>mechanisms</em>. For example for adding labels to input elements and for automatically displaying appropriate widgets for various association types. On top of that, I have two form builders that add <em>layout</em> specifics; one for CSS-based layouts, one for table-based layouts. I still need a further layer for <em>policy</em>: only show users what they are allowed to see and touch. This last policy layer is, of course, independent of layout (and vice versa!), therefore, short of full-fledged AOP, decoration was the way to go.</p>
<p><code>
<pre>
class DecoFormBuilder

  class &lt;&lt; self
    def new(object_name, object, template, options, proc)
      delegate_class = options.delete(:delegate_builder)
      raise ArgumentError, 'No :delegate_builder given to DecoFormBuilder' unless delegate_class
      decorate(delegate_class).new(object_name, object, template, options, proc)
    end

    private

    def decorate(klass)
      decorated = Class.new(klass)
      decorated.send(:include, Decoration)
      decorated
    end
  end

  module Decoration
    def initialize(object_name, object, template, option, proc)
      super
      # Do whatever initialization you need here
    end

    # Put the decorating methods here and don't forget to
    # call super.

  end
end
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2007/02/12/self-conscious-decoration/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Eclipse: Printing Editor Templates using XSLT, CSS, and Firefox</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2007/01/01/eclipse-printing-editor-templates-using-xslt-css-and-firefox/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2007/01/01/eclipse-printing-editor-templates-using-xslt-css-and-firefox/#comments</comments>
		<pubDate>Mon, 01 Jan 2007 11:02:46 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/?p=10</guid>
		<description><![CDATA[I&#8217;m using Eclipse with RadRails to edit my Ruby and Rails code (and, yes, I&#8217;ve used it for Java, way back when). Inside Eclipse the various text editors offer so-called templates. These are snippets of common code with placeholders for variable bits. Type in the abbreviation for a template, then type Ctrl-Space and the abbreviation [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m using <a href="http://www.eclipse.org/"><strong>Eclipse</strong></a> with <a href="http://www.radrails.org/"><strong>RadRails</strong></a> to edit my Ruby and Rails code (and, yes, I&#8217;ve used it for Java, way back when).</p>
<p>Inside Eclipse the various text editors offer so-called templates. These are snippets of common code with placeholders for variable bits. Type in the abbreviation for a template, then type Ctrl-Space and the abbreviation is expanded to the template code. For editing Ruby/Rails templates are available from the <a href="http://radrailstemplates.com/">RadRails Templates site</a>.</p>
<p>I&#8217;ve only recently started to use templates and I&#8217;m still early on the learning curve, that is, I haven&#8217;t memorized many of the abbreviations. Unfortunately, Eclipse itself only has a list of templates with their expansions in its modal Preferences window. That&#8217;s not very helpful when coding. What Eclipse does have is a function to export templates to XML and that&#8217;s what I did.</p>
<p>The exported file looks like this<br />
<code></p>
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;templates&gt;
  &lt;template autoinsert="true" context="ruby" deleted="false" description="tm - all? { |e| .. }" enabled="true" name="all"&gt;all? { |${e}| ${cursor} }
  &lt;/template&gt;
  &lt;template autoinsert="true" context="ruby" deleted="false" description="tm - alias_method .." enabled="true" name="am"&gt;alias_method :${new_name}, :${old_name}
  &lt;/template&gt;
  ...
&lt;/templates&gt;
</pre>
<p></code></p>
<p>The easiest approach I could think of to make this into something printable is this. First, transform it into HTML using an XSL stylesheet, then make the HTML pretty by styling it with an CSS stylesheet. Luckily, most of this can be done inside a web browser such as <strong>Firefox</strong> that understands XSLT.</p>
<p>Here&#8217;s the XSLT<br />
<code></p>
<pre>
&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

&lt;xsl:template match="/"&gt;
  &lt;html&gt;
    &lt;head&gt;
      &lt;xsl:apply-templates mode="head" /&gt;
      &lt;link rel="stylesheet" type="text/css" href="templates.css" /&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;xsl:apply-templates mode="body" /&gt;
    &lt;/body&gt;
  &lt;/html&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="title" mode="head"&gt;
  &lt;title&gt;
    &lt;xsl:value-of select="." /&gt;
  &lt;/title&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="title" mode="body"&gt;
  &lt;h1&gt;
    &lt;xsl:value-of select="." /&gt;
  &lt;/h1&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="templates" mode="body"&gt;
  &lt;dl&gt;
    &lt;xsl:apply-templates mode="body" /&gt;
  &lt;/dl&gt;
&lt;/xsl:template&gt;

&lt;xsl:template match="template" mode="body"&gt;
  &lt;dt&gt;
    &lt;xsl:value-of select="@name" /&gt;
  &lt;/dt&gt;
  &lt;dd&gt;
    &lt;xsl:value-of select="." /&gt;
  &lt;/dd&gt;
&lt;/xsl:template&gt;

&lt;/xsl:stylesheet&gt;
</pre>
<p></code></p>
<p>And the CSS stylesheet<br />
<code></p>
<pre>
html {
  font-family: sans-serif;
}

dt {
  border-top: 1px solid #aaa;
  padding-top: 0.2em;
  font-weight: bold;
}

dd {
  margin-top: 0.3em;
  margin-bottom: 1em;
  white-space: pre;
  font-family: monospace;
}
</pre>
<p></code></p>
<p>Now, these parts need to be connected. For this, it is necessary to slightly edit the original XML template file. For good measure, I throw in a title.</p>
<p><code></p>
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;?xml-stylesheet type="text/xsl" href="templates.xsl" ?&gt;
&lt;templates&gt;
  &lt;title&gt;RadRails Ruby Templates&lt;/title&gt;
  &lt;template ...&gt;
    ...
  &lt;/template&gt;
</pre>
<p></code></p>
<p>You may find that the indentation for the template code looks wrong. The reason is that the code contains tabs for indentation. Ruby convention is to indent by 2 spaces for each level, by contrast, Firefox apparently expands tabs to 8 spaces. A small glitch that can be rectified easily</p>
<p><code></p>
<pre>
$ sed -i 's/\t/  /g' template.xml
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2007/01/01/eclipse-printing-editor-templates-using-xslt-css-and-firefox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails: Almost Automatic Client-Side Validation</title>
		<link>http://www.schuerig.de/michael/blog/index.php/2006/12/15/rails-almost-automatic-client-side-validation/</link>
		<comments>http://www.schuerig.de/michael/blog/index.php/2006/12/15/rails-almost-automatic-client-side-validation/#comments</comments>
		<pubDate>Fri, 15 Dec 2006 02:37:44 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://schuerig.de/michael/blog/?p=8</guid>
		<description><![CDATA[Ruby on Rails already does a good job of specifying almost declaratively what conditions objects must meet to be considered valid&#8211;that is, how they are validated. Thus, in order to make sure that a Person&#8217;s last_name attribute does not exceed 100 characters, you would write something like this class Person &#60; ActiveRecord::Base validates_length_of :last_name, :maximum [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby on Rails already does a good job of specifying <em>almost</em> declaratively what conditions objects must meet to be considered valid&#8211;that is, how they are validated.</p>
<p>Thus, in order to make sure that a Person&#8217;s <tt>last_name</tt> attribute does not exceed 100 characters, you would write something like this</p>
<p><code></p>
<pre>
class Person &lt; ActiveRecord::Base
  validates_length_of :last_name, :maximum =&gt; 100
end
</pre>
<p></code></p>
<p>Somewhere in a view you&#8217;ll probably refer to the <tt>last_name</tt> attribute like this</p>
<p><code></p>
<pre>
&lt;% form_for :person, @person, :url =&gt; { :action =&gt; "update" } do |f| -%&gt;
  Last name : &lt;%= f.text_field :last_name %&gt;
  &lt;%= submit_tag %&gt;
&lt;% end -%&gt;
</pre>
<p></code></p>
<p>There you get a nice form where users can enter last names as long as they may wish&#8211;only to be shown an error message complaining about the length in cases where they have unwittingly overshot the limit. How should they have known?</p>
<p>Well, as a nice and caring person you could add an annotation to each input field saying how long its contents are allowed to be. That would be slightly better, but still leaves more work for the users than necessary.</p>
<p>How about this: Users are immediately notified in an unobtrusive way that some of the content they have (or have not yet) filled into a form does not constitute valid data. Furthermore, users are kept from submitting a form that contains obviously invalid data.</p>
<p>Should be easy, shouldn&#8217;t it? Yes, it should and actually it is just two plugins away.</p>
<h3>Raising awareness of validations</h3>
<p>Out of the box, Rails handles validations in such a way that it adds callbacks for checking them to model classes, but otherwise immediately loses awareness of them. When later on in the lifecycle of a model instance validations are checked, Rails does so on autopilot. A model class just does it&#8217;s thing, it won&#8217;t tell you what it&#8217;s doing, but you can be sure it&#8217;ll complain when something is wrong. Let&#8217;s add some reflection to make model classes a bit more loquacious. The details are irrelevant, just install the <b>Validation Reflection</b> plugin into your Rails application</p>
<p><code></p>
<pre>
$ script/plugin install svn://rubyforge.org//var/svn/valirefl/validation_reflection/trunk
</pre>
<p></code></p>
<h3>Tell the browser</h3>
<p>So far, the newfound awareness of validations idles away on the server-side. Somehow it has to be transported to the user&#8217;s browser. That is one of the things the <b>Client-Side Validation</b> plugin does. Install with</p>
<p><code></p>
<pre>
$ script/plugin install svn://rubyforge.org//var/svn/clientsidevali/client_side_validation/trunk
</pre>
<p></code></p>
<p>The first thing this plugin does is that it enhances tags generated by Rails&#8217;s helper methods in such a way that they contain encoded information about the validation constraints that apply to their values.</p>
<h3>Engage the client</h3>
<p>Still, even though validation information has been inserted into the HTML sent to the browser, where it lays dormant. On the client-side, JavaScript is where the action is. Therefore the task of checking validations there is handled by a validator written in JavaScript included with the Client-Side Validation plugin.</p>
<p>The generic script for the validator is included in your views or layout as part of the default scripts, therefore it is probably just there already.</p>
<p><code></p>
<pre>
&lt;%= javascript_include_tag :defaults %&gt;
</pre>
<p></code></p>
<p>Here we come to a point where you, the programmer, have to make some decisions and do some work. First, you need to decide (or have your code decide) what locale your users are in. Remember, dates don&#8217;t look the same all over the world.</p>
<p><code></p>
<pre>
 &lt;%= javascript_include_tag 'validators-en' %&gt;
</pre>
<p></code></p>
<p>Currently English (<tt>en</tt>) and German (<tt>de</tt>) are supported.</p>
<p>Then, you have to tell the validator that there&#8217;s work for it to do. For this, all forms that ought to be validated have to be marked with the <em>class</em> <tt>validated</tt>. Thus, the above form becomes</p>
<p><code></p>
<pre>
&lt;% form_for :person, @person, :url =&gt; { :action =&gt; "update" }, <span style="color:#f00">:html =&gt; { :class =&gt; 'validated' }</span> do |f| -%&gt;
  Last name : &lt;%= f.text_field :last_name %&gt;
  &lt;%= submit_tag %&gt;
&lt;% end -%&gt;
</pre>
<p></code></p>
<p>Also, you need to nudge the validator to start looking at the forms by adding a line to <tt>public/javascripts/application.js</tt></p>
<p><code></p>
<pre>
Form.Validator.installForAllValidatedForms();
</pre>
<p></code></p>
<h3>You ain&#8217;t see nothing yet</h3>
<p>If you&#8217;ve followed all these steps, the validator is probably doing its work, but hardly see anything of it. You may notice that the submit button is enabled when the form is valid and disabled when it is invalid, but that is all there is.</p>
<p>A further, but still invisible, thing that the validator does is that it adds (removes) the class &#8220;<tt>invalid</tt>&#8221; to input elements when they are invalid. Making this change in attribute visible is a small matter of CSS</p>
<p><code></p>
<pre>
 .invalid {
   border: 1px solid #f00;
 }
</pre>
<p></code></p>
<p>The result is not pretty, but you can push your stylesheeting abilities to the limit to make them look however you like. Also, the validator offers hooks for customizing most aspects. But that is left for a future installment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.schuerig.de/michael/blog/index.php/2006/12/15/rails-almost-automatic-client-side-validation/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>

