<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>FozWorks - Home</title>
  <id>tag:www.fozworks.com,2009:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  
  <link href="http://www.fozworks.com/" rel="alternate" type="text/html" />
  <updated>2009-11-01T17:43:33Z</updated>
  <link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/3.0/" /><link rel="self" href="http://feeds.feedburner.com/fozworks" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2009-10-31:6007</id>
    <published>2009-10-31T15:00:00Z</published>
    <updated>2009-11-01T17:43:33Z</updated>
    <category term="code" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/H-8vZr6HUgM/peggy2-halloween-sketch" rel="alternate" type="text/html" />
    <title>Peggy2 Halloween Sketch</title>
<content type="html">
            &lt;p&gt;I made a little Arduino sketch for my &lt;a href="http://evilmadscience.com/tinykitlist/75"&gt;Peggy2&lt;/a&gt;.&lt;/p&gt;


&amp;lt;object height="300" width="400"&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;param /&gt;&amp;lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=7362447&amp;amp;amp;server=vimeo.com&amp;amp;amp;show_title=1&amp;amp;amp;show_byline=1&amp;amp;amp;show_portrait=0&amp;amp;amp;color=&amp;amp;amp;fullscreen=1" height="300" width="400"&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/7362447"&gt;Peggy2 Halloween&lt;/a&gt; from &lt;a href="http://vimeo.com/user1587018"&gt;Jeremy Seitz&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;Source code is here:
&lt;a href="http://github.com/somebox/peggy2-halloween"&gt;http://github.com/somebox/peggy2-halloween&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Happy Halloween!!!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/H-8vZr6HUgM" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2009/10/31/peggy2-halloween-sketch</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2008-09-05:1395</id>
    <published>2008-09-05T23:06:00Z</published>
    <updated>2008-09-05T23:09:13Z</updated>
    <category term="rake" />
    <category term="sphinx" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/ipEvBQAo3NQ/rake-installation-of-sphinx-in-mac-osx" rel="alternate" type="text/html" />
    <title>Automated Sphinx Install in Mac OS X Using Rake</title>
<content type="html">
            &lt;p&gt;One challenge for any team building a Rails project with &lt;a href="http://www.sphinxsearch.com/"&gt;Sphinx&lt;/a&gt;: keeping everyone up to date, on the same version of searchd. We wanted to make sure it was installed the same way, same version, on everyone's dev machine. And we all work remotely of course :)&lt;/p&gt;

&lt;p&gt;The solution for us was a &lt;strong&gt;rake task that downloads, compiles and installs Sphinx on OS X&lt;/strong&gt; Leopard. We assume that you previously installed the developer tools (Mac OS X Install Disc 2, XCode).&lt;/p&gt;

&lt;p&gt;To get the compile to work, you need to install mysql5 via &lt;a href="http://macports.org"&gt;MacPorts&lt;/a&gt; so you have the correct libs available. &lt;code&gt;sudo port install mysql5&lt;/code&gt; Alas, we never were able to get Leopard's MySQL libs to compile with Sphinx correctly. But never fear, installing MySQL via MacPorts will not affect the standard Apple mysqld server or client in any way.&lt;/p&gt;

&lt;h3&gt;lib/tasks/sphinx.rake  :&lt;/h3&gt;
&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;&lt;span class="meta meta_require meta_require_ruby"&gt;&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;require&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;/config/environment.rb&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;SPHINX_SOURCE&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;http://www.sphinxsearch.com/downloads/sphinx-0.9.8-rc2.tar.gz&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; r1234
&lt;/span&gt;
namespace &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;sphinx&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do  
&lt;/span&gt;  desc &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Install Sphinx from source&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
  task &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;install&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do
&lt;/span&gt;    build_dir &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="meta meta_environment-variable meta_environment-variable_ruby"&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;ENV&lt;/span&gt;[&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;HOME&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;]&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;/tmp/sphinx&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
    system &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;rm -rf &lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;build_dir&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
    system &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;mkdir -p &lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;build_dir&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
    puts &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Downloading Sphinx indexer from &lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;SPHINX_SOURCE&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
    cd build_dir &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do 
&lt;/span&gt;      uri &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;URI&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;parse&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;SPHINX_SOURCE&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
      tarball &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;basename&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;uri&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;path&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
      &lt;span class="support support_class support_class_ruby"&gt;Net&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;HTTP&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;start&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;uri&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;host&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;http&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;
        resp &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; http&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;get&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;uri&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;path&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
        open&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;tarball&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;wb&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;file&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;
          file&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;write&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;resp&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;body&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
        &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
      &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
      system&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;tar -xzf &lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;tarball&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
      cd &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;build_dir&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;/&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;tarball&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;gsub&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;.tar.gz&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do
&lt;/span&gt;        system&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;./configure --with-mysql-libs=/opt/local/lib/mysql5/mysql/ --with-mysql-includes=/opt/local/include/mysql5/mysql/&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
        system&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;make&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
        puts &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;&lt;span class="constant constant_character constant_character_escape constant_character_escape_ruby"&gt;\n&lt;/span&gt;Running 'sudo make install' - this will install Sphinx.&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
        system&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;sudo make install&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
      &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
    &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;  
  system&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;sudo mkdir -p /opt/local/var/db/sphinx&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
  system&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;sudo chown -R `whoami` /opt/local/var/db/sphinx&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt; 
&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/ipEvBQAo3NQ" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2008/9/5/rake-installation-of-sphinx-in-mac-osx</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2008-06-07:602</id>
    <published>2008-06-07T15:04:00Z</published>
    <updated>2008-06-09T19:03:34Z</updated>
    <category term="rails" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/H4n2hrBcsC4/the-worst-rails-code" rel="alternate" type="text/html" />
    <title>The Worst Rails Code</title>
<summary type="html">&lt;p&gt;I just came back from &lt;a href="http://en.oreilly.com/rails2008/public/content/home"&gt;RailsConf 2008&lt;/a&gt; in Portland. This year was great. There were a lot of exciting developments to talk about, like &lt;a href="http://ruby.gemstone.com/"&gt;MagLev&lt;/a&gt;, &lt;a href="http://skynet.rubyforge.org/"&gt;SkyNet&lt;/a&gt;, &lt;a href="http://www.modrails.com/"&gt;mod_rails&lt;/a&gt; and &lt;a href="http://weblog.rubyonrails.org/2008/6/1/rails-2-1-time-zones-dirty-caching-gem-dependencies-caching-etc"&gt;Rails 2.1&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The talks seemed better this year as well. The one I was most looking forward to was from &lt;a href="http://blog.obiefernandez.com/"&gt;Obie Fernandez&lt;/a&gt;, who wrote &lt;a href="http://www.amazon.com/gp/product/0321445619?ie=UTF8&amp;amp;#38;tag=obiefernandez-20&amp;amp;#38;link_code=as3&amp;amp;#38;camp=211189&amp;amp;#38;creative=373489&amp;amp;#38;creativeASIN=0321445619"&gt;The Rails Way&lt;/a&gt;, published last fall. I can easily say this is the best Rails book published to date (sorry, Pragmatic). It’s packed with useful information, best practices, and real-world code. Obie’s excellent writing style along with contributions from numerous Rails coders make it a great read too. My copy is already showing wear. And at 900+ pages, it’s like a phone book.&lt;/p&gt;


	&lt;p&gt;Obie’s talk was given to a packed room, despite being scheduled on Sunday morning at 9am. The title of the talk, “&lt;a href="http://blog.obiefernandez.com/content/2008/06/railsconf-2008.html"&gt;The Worst Rails Code You’ve Ever Seen (and how not to write it yourself)&lt;/a&gt;”, discouraged my friends from attending (“sounds depressing”, one said). During the first lightning round, we had seen some pretty bad code proudly presented (to which Ryan Davis publicly expressed his horror).&lt;/p&gt;


	&lt;p&gt;But the talk was worth getting up for. Through a series of real-world examples, Obie (and co-presenter &lt;a href="http://reinh.com/"&gt;Rein Henrichs&lt;/a&gt;) showed the audience just how bad Rails coding can get. Some of the code was truly appalling, like a 1200+ line app in a single controller (no, really). Other examples looked, well, kind of familiar. Having been involved in several Rails projects myself since 2005, I’ve seen (and written) my share of bad code.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I just came back from &lt;a href="http://en.oreilly.com/rails2008/public/content/home"&gt;RailsConf 2008&lt;/a&gt; in Portland. This year was great. There were a lot of exciting developments to talk about, like &lt;a href="http://ruby.gemstone.com/"&gt;MagLev&lt;/a&gt;, &lt;a href="http://skynet.rubyforge.org/"&gt;SkyNet&lt;/a&gt;, &lt;a href="http://www.modrails.com/"&gt;mod_rails&lt;/a&gt; and &lt;a href="http://weblog.rubyonrails.org/2008/6/1/rails-2-1-time-zones-dirty-caching-gem-dependencies-caching-etc"&gt;Rails 2.1&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The talks seemed better this year as well. The one I was most looking forward to was from &lt;a href="http://blog.obiefernandez.com/"&gt;Obie Fernandez&lt;/a&gt;, who wrote &lt;a href="http://www.amazon.com/gp/product/0321445619?ie=UTF8&amp;amp;#38;tag=obiefernandez-20&amp;amp;#38;link_code=as3&amp;amp;#38;camp=211189&amp;amp;#38;creative=373489&amp;amp;#38;creativeASIN=0321445619"&gt;The Rails Way&lt;/a&gt;, published last fall. I can easily say this is the best Rails book published to date (sorry, Pragmatic). It’s packed with useful information, best practices, and real-world code. Obie’s excellent writing style along with contributions from numerous Rails coders make it a great read too. My copy is already showing wear. And at 900+ pages, it’s like a phone book.&lt;/p&gt;


	&lt;p&gt;Obie’s talk was given to a packed room, despite being scheduled on Sunday morning at 9am. The title of the talk, “&lt;a href="http://blog.obiefernandez.com/content/2008/06/railsconf-2008.html"&gt;The Worst Rails Code You’ve Ever Seen (and how not to write it yourself)&lt;/a&gt;”, discouraged my friends from attending (“sounds depressing”, one said). During the first lightning round, we had seen some pretty bad code proudly presented (to which Ryan Davis publicly expressed his horror).&lt;/p&gt;


	&lt;p&gt;But the talk was worth getting up for. Through a series of real-world examples, Obie (and co-presenter &lt;a href="http://reinh.com/"&gt;Rein Henrichs&lt;/a&gt;) showed the audience just how bad Rails coding can get. Some of the code was truly appalling, like a 1200+ line app in a single controller (no, really). Other examples looked, well, kind of familiar. Having been involved in several Rails projects myself since 2005, I’ve seen (and written) my share of bad code.&lt;/p&gt;
&lt;p&gt;I just came back from &lt;a href="http://en.oreilly.com/rails2008/public/content/home"&gt;RailsConf 2008&lt;/a&gt; in Portland. This year was great. There were a lot of exciting developments to talk about, like &lt;a href="http://ruby.gemstone.com/"&gt;MagLev&lt;/a&gt;, &lt;a href="http://skynet.rubyforge.org/"&gt;SkyNet&lt;/a&gt;, &lt;a href="http://www.modrails.com/"&gt;mod_rails&lt;/a&gt; and &lt;a href="http://weblog.rubyonrails.org/2008/6/1/rails-2-1-time-zones-dirty-caching-gem-dependencies-caching-etc"&gt;Rails 2.1&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The talks seemed better this year as well. The one I was most looking forward to was from &lt;a href="http://blog.obiefernandez.com/"&gt;Obie Fernandez&lt;/a&gt;, who wrote &lt;a href="http://www.amazon.com/gp/product/0321445619?ie=UTF8&amp;amp;#38;tag=obiefernandez-20&amp;amp;#38;link_code=as3&amp;amp;#38;camp=211189&amp;amp;#38;creative=373489&amp;amp;#38;creativeASIN=0321445619"&gt;The Rails Way&lt;/a&gt;, published last fall. I can easily say this is the best Rails book published to date (sorry, Pragmatic). It’s packed with useful information, best practices, and real-world code. Obie’s excellent writing style along with contributions from numerous Rails coders make it a great read too. My copy is already showing wear. And at 900+ pages, it’s like a phone book.&lt;/p&gt;


	&lt;p&gt;Obie’s talk was given to a packed room, despite being scheduled on Sunday morning at 9am. The title of the talk, “&lt;a href="http://blog.obiefernandez.com/content/2008/06/railsconf-2008.html"&gt;The Worst Rails Code You’ve Ever Seen (and how not to write it yourself)&lt;/a&gt;”, discouraged my friends from attending (“sounds depressing”, one said). During the first lightning round, we had seen some pretty bad code proudly presented (to which Ryan Davis publicly expressed his horror).&lt;/p&gt;


	&lt;p&gt;But the talk was worth getting up for. Through a series of real-world examples, Obie (and co-presenter &lt;a href="http://reinh.com/"&gt;Rein Henrichs&lt;/a&gt;) showed the audience just how bad Rails coding can get. Some of the code was truly appalling, like a 1200+ line app in a single controller (no, really). Other examples looked, well, kind of familiar. Having been involved in several Rails projects myself since 2005, I’ve seen (and written) my share of bad code.&lt;/p&gt;


	&lt;p&gt;The talk started out with a bit of an elitist air, with the presenters snobbishly laughing at common mistakes. But as the talk wore on, the tone changed and became more helpful. At one point Obie showed some pretty ugly code and then admitted that he had actually written it.&lt;/p&gt;


	&lt;p&gt;But what really struck me about this talk was how programmers (myself included) often are unaware of “best practices”, or simply don’t understand Rails and Ruby well enough.&lt;/p&gt;


	&lt;p&gt;Now some of you reading this may think it’s all pretty obvious, basic stuff. But we all write bad code sometimes, even the slickest meta-programmers I know do. Here’s what I took away from the talk:&lt;/p&gt;


	&lt;h3&gt;Common Reasons People Write Bad Code&lt;/h3&gt;


	&lt;p&gt;1) Folks just don’t write tests, and as a result, they are afraid to refactor (and therefore improve) their code. It’s painful and dangerous to refactor without tests.&lt;/p&gt;


	&lt;p&gt;2) They are too lazy to look up the correct way to do something, either because they don’t like to read and research, or because they assume it will take longer than just “figuring it out”.&lt;/p&gt;


	&lt;p&gt;3) They Google for a solution to a problem and come across bad or misleading examples on someone’s blog (or a DZone snippet). You just can’t assume that because it’s posted on someone’s blog that it’s  correct. In reality, you should be suspicious of posts without comments or attribution. There are a ton of bad snippets and pasties out there.&lt;/p&gt;


	&lt;h3&gt;What Is Bad Code?&lt;/h3&gt;


	&lt;p&gt;It’s so important to understand the Rails framework. Rails already provides us with many best practices and time savers. It’s silly to waste time re-inventing an already solved problem.&lt;/p&gt;


	&lt;p&gt;Many of the examples from the talk confirmed that people are struggling with parameters, hashes, and passing data between controller actions.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Ruby’s &lt;a href="http://www.ruby-doc.org/core/classes/Hash.html"&gt;Hash&lt;/a&gt; class gives us &lt;a href="http://www.ruby-doc.org/core/classes/Hash.html#M000191"&gt;merge&lt;/a&gt; and other useful methods, so there’s often no need to iterate over values or put in explicit assignments. &lt;/li&gt;
		&lt;li&gt;The Rails &lt;strong&gt;session&lt;/strong&gt; object is the proper way to pass data between controller actions, and the &lt;strong&gt;flash&lt;/strong&gt; object is there for displaying messages to the user (and let’s not forget flash.now for &lt;span class="caps"&gt;AJAX&lt;/span&gt; actions). Don’t use instance variables to pass messages to the view.&lt;/li&gt;
		&lt;li&gt;If you have validations on parameters in the controller, they should probably be in the model instead (validates_presence_of, etc).&lt;/li&gt;
		&lt;li&gt;Manipulating parameters outside of the context of a model (or other container) feels like &lt;span class="caps"&gt;PHP&lt;/span&gt;. It’s much nicer to call &lt;code&gt;MyModel.new(params[:my_model])&lt;/code&gt; and then validate. Why muck around with things like &lt;code&gt;params[person][date][i1]&lt;/code&gt;, etc?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Other less-obvious suggestions to help clean up bad code included:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Use attr_protected in models instead of worrying about how certain parameters might be set via the url or hacked forms&lt;/li&gt;
		&lt;li&gt;Avoid creating a big config class. Instead, use constants, and put them in the classes that need them.&lt;/li&gt;
		&lt;li&gt;application.rb should only be for actions, put utility methods somewhere else. Like a module, or in models.&lt;/li&gt;
		&lt;li&gt;Consider using the &lt;a href="http://blog.jayfields.com/2007/03/rails-presenter-pattern.html"&gt;presenter pattern&lt;/a&gt; to clean up code&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Where To Turn For Help&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.amazon.com/Ruby-Way-Second-Addison-Wesley-Professional/dp/0672328844"&gt;The Ruby Way, 2nd ed.&lt;/a&gt; (&lt;a href="http://rubyhacker.com/"&gt;Hal Fulton&lt;/a&gt;) and &lt;a href="http://www.amazon.com/Rails-Way-Addison-Wesley-Professional-Ruby/dp/0321445619"&gt;The Rails Way&lt;/a&gt;. They are both excellent.&lt;/li&gt;
		&lt;li&gt;Refer to the Rails &lt;span class="caps"&gt;API&lt;/span&gt; and Ruby standard library documentation as a primary resource&lt;/li&gt;
		&lt;li&gt;When you are having trouble understanding how to use a plugin, Gem, or Rails itself, don’t be afraid to &lt;strong&gt;look at the source code&lt;/strong&gt;. It’s Ruby after all, and often surprisingly easy to understand.&lt;/li&gt;
		&lt;li&gt;Search (or post) on an appropriate &lt;span class="caps"&gt;IRC&lt;/span&gt; channel or forum&lt;/li&gt;
		&lt;li&gt;Study other people’s code. I learn a lot this way. Some of my favorites: Rick Olson, Ryan Davis, Eric Hodel and Evan Weaver.&lt;/li&gt;
		&lt;li&gt;Use script/console: this is often a really fast way to try a concept out, play with it and verify that it will really work.&lt;/li&gt;
		&lt;li&gt;Keep a library of your own code snippets. When you run across something useful, copy and paste it into a file locally that you can search through later.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Don’t Code Solo&lt;/h3&gt;


	&lt;p&gt;Obie also strongly recommended pair programming. Working with other programmers is a really great way to learn quickly. He specifically suggested pairing with a senior coder (like, a Smalltalk guru). For most of this, that’s not a realistic option, unless you are lucky enough to have expert contacts who are willing to spend that kind of time with you. But I can certainly agree that it’s so helpful to work through code with another person.&lt;/p&gt;


	&lt;p&gt;To that extent, I also found the talk about &lt;a href="http://en.oreilly.com/rails2008/public/schedule/detail/1924"&gt;Remote Pair Programing&lt;/a&gt; interesting, especially since I spend a lot of time in Europe while working on projects in the US. I definitely plan to pair program more often now!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/H4n2hrBcsC4" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2008/6/7/the-worst-rails-code</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2008-05-23:553</id>
    <published>2008-05-23T06:21:00Z</published>
    <updated>2008-05-23T06:22:39Z</updated>
    <category term="awards" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/uNyzYyQrHoU/democracynow-com-is-a-webby-honoree" rel="alternate" type="text/html" />
    <title>DemocracyNow.com is a Webby Honoree</title>
<content type="html">
            &lt;p&gt;Wow, I just found out today that &lt;a href="http://democracynow.org"&gt;Democracy Now!&lt;/a&gt; was a honoree this year in the &lt;a href="http://www.webbyawards.com/webbys/current_honorees.php?media_id=96&amp;amp;#38;category_id=45&amp;amp;#38;season=12"&gt;News&lt;/a&gt;, &lt;a href="http://www.webbyawards.com/webbys/current_honorees.php?category_id=50"&gt;Political&lt;/a&gt; and &lt;a href="http://www.webbyawards.com/webbys/current_honorees.php?category_id=89"&gt;Podcast&lt;/a&gt; categories. Congrats to everyone on the web dev team – it’s exciting to see our Rails effort up there ranked with such big names!&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://democracynow.org"&gt;&lt;img src="http://www.fozworks.com/assets/2008/5/23/dn-logo-for-podcast.png" alt="Democracy Now!" /&gt;&lt;/a&gt;&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/uNyzYyQrHoU" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2008/5/23/democracynow-com-is-a-webby-honoree</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2008-05-01:467</id>
    <published>2008-05-01T12:59:00Z</published>
    <updated>2008-06-09T19:04:22Z</updated>
    <category term="rails" />
    <category term="ruby" />
    <category term="sphinx" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/VfPmtmFY2wQ/geodistance-searching-with-ultrasphinx" rel="alternate" type="text/html" />
    <title>Geodistance Searching with Ultrasphinx</title>
<summary type="html">&lt;p&gt;I’m happy to annouce a patch for &lt;a href="http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html"&gt;Ultrasphinx&lt;/a&gt; that enables access to the geographical distance searching in the &lt;a href="http://www.sphinxsearch.com/"&gt;Sphinx&lt;/a&gt; full-text search engine.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I’m happy to annouce a patch for &lt;a href="http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html"&gt;Ultrasphinx&lt;/a&gt; that enables access to the geographical distance searching in the &lt;a href="http://www.sphinxsearch.com/"&gt;Sphinx&lt;/a&gt; full-text search engine.&lt;/p&gt;
&lt;p&gt;I’m happy to annouce a patch for &lt;a href="http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html"&gt;Ultrasphinx&lt;/a&gt; that enables access to the geographical distance searching in the &lt;a href="http://www.sphinxsearch.com/"&gt;Sphinx&lt;/a&gt; full-text search engine.&lt;/p&gt;


&lt;h3&gt;Why&lt;/h3&gt;

	&lt;p&gt;Through my company &lt;a href="http://somebox.com"&gt;Somebox&lt;/a&gt;, I recently led a team that launched &lt;a href="http://travelskoot.com"&gt;TravelSkoot.com&lt;/a&gt; for &lt;span class="caps"&gt;NBC&lt;/span&gt; Digital Innovation, which is a Google Maps mash-up that allows people to group travel destinations together (called “skoots”) along with comments, ratings, etc. The entire project was built in Rails in about four months, and is living at &lt;a href="http://engineyard.com"&gt;EngineYard&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;One of the challenges was to come up with an efficient way to search a large number of points, along with other metadata and fulltext searching. Normally, we would use &lt;a href="http://geokit.rubyforge.org/"&gt;GeoKit&lt;/a&gt; for this kind of thing, but once you combine fulltext with lots of other filters, things get complicated (and slow). That’s where &lt;a href="http://www.sphinxsearch.com/"&gt;Sphinx&lt;/a&gt; really shines.&lt;/p&gt;


	&lt;p&gt;I knew that Sphinx had &lt;a href="http://www.sphinxsearch.com/doc.html#api-func-setgeoanchor"&gt;support for geodistance&lt;/a&gt;, but unfortunately none of the Rails plugins did at the time. UltraSphinx offers more features than any of the other Rails/Sphinx plugins, and is based on Pat Allan’s excellent &lt;a href="http://riddle.freelancing-gods.com/"&gt;Riddle Client&lt;/a&gt;, which already had the basics for geodistance baked in (and required only &lt;a href="http://code.google.com/p/rails-oceania/source/detail?r=559"&gt;a tiny patch&lt;/a&gt; to make it work right). The rest of the changes were then made to the UltraSphinx plugin to make it usable.&lt;/p&gt;


&lt;h3&gt;How it Works&lt;/h3&gt;

	&lt;p&gt;To set up UltraSphinx for geodistance searches, you need to declare your latitude and longitude columns in the model. Since Sphinx expects these to be stored in radians, you can use the :function_sql option of is_indexed to do the conversion:&lt;/p&gt;


&lt;pre&gt;
class Point &amp;lt; ActiveRecord::Base
  is_indexed :fields =&amp;gt; [
    :title,
    :description,
    {:field =&amp;gt; "lat", :function_sql =&amp;gt; 'RADIANS(?)'},
    {:field =&amp;gt; "lng", :function_sql =&amp;gt; 'RADIANS(?)'}
  ]
end
&lt;/pre&gt;

	&lt;p&gt;The search itself ends up looking like this:&lt;/p&gt;


&lt;pre&gt;
@search = Ultrasphinx::Search.new(
  :query          =&amp;gt; 'pizza',
  :sort_mode   =&amp;gt; 'extended',
  :sort_by        =&amp;gt; 'distance asc',
  :filters        =&amp;gt; {'distance' =&amp;gt; 0..10000},
  :location =&amp;gt; {
    :units =&amp;gt; 'degrees',
    :lat =&amp;gt; 40.343,
    :long =&amp;gt; -74.233
  }
)
@search.run
&lt;/pre&gt;

	&lt;p&gt;The actual distance is then available in your models (in meters):&lt;/p&gt;


&lt;pre&gt;
@search.results.first.distance
&lt;/pre&gt;

	&lt;p&gt;You can also filter and sort results by distance and combine all the other features of UltraSphinx (faceting, weighting, etc).&lt;/p&gt;


&lt;h3&gt;Thanks&lt;/h3&gt;

	&lt;p&gt;Open source rocks. &lt;a href="http://www.workingwithrails.com/person/7739-evan-weaver"&gt;Evan Weaver&lt;/a&gt; was very encouraging in helping this patch along, cleaning up the &lt;span class="caps"&gt;API&lt;/span&gt;, and guiding discussion. A lot of support came through &lt;a href="http://www.workingwithrails.com/person/12039-dr-mark-lane"&gt;Dr. Mark Lane&lt;/a&gt;, who helped guide me through the internals, rewrote the tests in his roll-up patches, and pushed me to finish. Also thanks to &lt;a href="http://workingwithrails.com/person/8564-michael-hill"&gt;Michael Hill&lt;/a&gt;, &lt;a href="http://bumi.wordpress.com/"&gt;Michael Burmann&lt;/a&gt;, and &lt;a href="http://rubyforge.org/users/jasonlee9/"&gt;Jason Lee&lt;/a&gt; for testing and feedback.&lt;/p&gt;


&lt;h3&gt;Footnotes&lt;/h3&gt;

	&lt;p&gt;In order to use the geodistance features of UltraSphinx, you need to be using version 1.10 or higher (which also requires at minimum Sphinx v1198). These geo features are still young, and not without some minor issues. Be sure to consult the &lt;a href="http://rubyforge.org/forum/forum.php?forum_id=14244"&gt;forum&lt;/a&gt; for answers (or submit a patch!), or leave a comment here if you need help. And if you end up using this patch in your project, &lt;a href="http://workingwithrails.com/recommendation/new/person/8561-jeremy-seitz"&gt;recommend me at &lt;span class="caps"&gt;WWR&lt;/span&gt;&lt;/a&gt;!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/VfPmtmFY2wQ" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2008/5/1/geodistance-searching-with-ultrasphinx</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2008-04-28:454</id>
    <published>2008-04-28T23:19:00Z</published>
    <updated>2008-06-29T08:01:41Z</updated>
    <category term="code" />
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/PHV221VIitw/syntactical-sugar" rel="alternate" type="text/html" />
    <title>Syntactical Sugar</title>
<content type="html">
            &lt;p&gt;On recent rails projects, I found myself clinging to a few useful helpers and additions. Here’s a few.&lt;/p&gt;


	&lt;h2&gt;hide_unless&lt;/h2&gt;


	&lt;p&gt;Often in views, I find I want to hide a particular div or element, but only if certain conditions are met. An ajax call might later reveal it, or replace the contents of the div with something.&lt;/p&gt;


&lt;pre&gt;
 def hide_unless(condition)
    condition ? '' : 'display:none'
 end
&lt;/pre&gt;

	&lt;p&gt;In use:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;div id="edit_pane" style="&amp;lt;%= hide_unless(@story) %&amp;gt;"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/pre&gt;

	&lt;h2&gt;present?&lt;/h2&gt;


	&lt;p&gt;Rails gives us .blank?, but I hate writing things like:&lt;/p&gt;


&lt;pre&gt;
  &amp;lt;% if !@stories.blank? %&amp;gt;
    ... etc
  &amp;lt;% end %&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;So, I add this as an extension in my projects:&lt;/p&gt;


&lt;pre&gt;
class Object
  def present?
    !blank?
  end
end
&lt;/pre&gt;

	&lt;p&gt;And obviously it works on anything: arrays, hashes, nil, etc.&lt;/p&gt;


&lt;pre&gt;
  &amp;lt;% if session[:setting].present? %&amp;gt;
   etc...
  &amp;lt;% end %&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;&lt;b&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt; (29-Jun-2008)&lt;/b&gt;: &lt;span class="caps"&gt;DHH&lt;/span&gt; just &lt;a href="http://github.com/rails/rails/commit/a3caf28da3a22c1326d3d98dcf71483a8edaa55a"&gt;committed this to Edge Rails&lt;/a&gt;. I have no proof that I had anything to do with it, but I’ll pretend :)&lt;/p&gt;


	&lt;h2&gt;user_owns_it&lt;/h2&gt;


	&lt;p&gt;A common task is to check if the current user owns a particular resource.&lt;/p&gt;


&lt;pre&gt;
  def user_owns_it(asset)
    asset.respond_to?(:created_by) and asset.created_by and current_user and asset.created_by.id == current_user.id
  end
&lt;/pre&gt;

	&lt;p&gt;This allows easy checking in views:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;% if user_owns_it(@post) %&amp;gt;
   link_to "Edit Your Post", edit_post_path(@post)
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;

&lt;hr /&gt;
Please share if you have other interesting tidbits from your toolbox!
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/PHV221VIitw" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2008/4/28/syntactical-sugar</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2008-04-18:393</id>
    <published>2008-04-18T16:31:00Z</published>
    <updated>2008-04-18T18:52:07Z</updated>
    <link href="http://feedproxy.google.com/~r/fozworks/~3/jI--r7wd89k/fix-for-slow-gem-updates" rel="alternate" type="text/html" />
    <title>Fix for slow gem updates</title>
<content type="html">
            &lt;p&gt;Lately, rubygems seems to be slow when updating. I guess there’s a lot more gems being released than ever before. As a result, running gem update is painful:&lt;/p&gt;


&lt;pre&gt;
$ sudo gem update
Updating installed gems...
Updating metadata for 345 gems from http://gems.rubyforge.org
....................... 
&lt;/pre&gt;

	&lt;p&gt;Argh! Turns out that there’s a “buik update” setting, and the default threshold is 1000. Metadata will be downloaded a gem at a time if there are 999 to get. Fortunately, it can be changed, by passing the -B flag to gem commands, or you can put this in ~/.gemrc :&lt;/p&gt;


&lt;pre&gt;
update: -B 10
install: -B 10
&lt;/pre&gt;

	&lt;p&gt;Now your gem updates will be much faster.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href="http://blog.zenspider.com/"&gt;zenspider&lt;/a&gt; notes: &lt;em&gt;the latest (last 2 actually) version of rubygems has http keepalive so it should be much much much faster and the bulk update threshold setting shouldn’t be necessary.&lt;/em&gt;&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/jI--r7wd89k" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2008/4/18/fix-for-slow-gem-updates</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2008-04-09:334</id>
    <published>2008-04-09T20:17:00Z</published>
    <updated>2008-04-09T20:36:21Z</updated>
    <category term="code" />
    <category term="ruby" />
    <category term="sound" />
    <category term="testing" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/W2tb1OqhEG4/autotest-sounds-with-playlists" rel="alternate" type="text/html" />
    <title>Autotest Sounds with playlists!</title>
<content type="html">
            &lt;p&gt;Ken Collins put together an awesome update to the autotest sound plugin. His version supports a playlist directory, so you can easily cycle through different init, red and green sounds. His sounds are hilarious!&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.metaskills.net/2008/4/6/autotest-playlist-for-red-green-feedback"&gt;http://www.metaskills.net/2008/4/6/autotest-playlist-for-red-green-feedback&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I’ve been using it all day :)&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/W2tb1OqhEG4" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2008/4/9/autotest-sounds-with-playlists</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2007-12-23:63</id>
    <published>2007-12-23T07:10:00Z</published>
    <updated>2008-02-03T21:56:17Z</updated>
    <category term="configs" />
    <category term="irb" />
    <category term="rails" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/8hPkRll_AWY/my-irbrc" rel="alternate" type="text/html" />
    <title>My .irbrc</title>
<content type="html">
            &lt;p&gt;Some collected recipes to make irb and script/console a bit nicer to use:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;pretty printing (&lt;code&gt;pp whatever&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;enhanced tab completion&lt;/li&gt;
		&lt;li&gt;rails logging to console&lt;/li&gt;
		&lt;li&gt;saves command history between sessions&lt;/li&gt;
		&lt;li&gt;use readline extensions module&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Tips were collected from posts by &lt;a href="http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/"&gt;Dr. Nic&lt;/a&gt;, &lt;a href="http://toolmantim.com/article/2007/2/6/system_wide_script_console_logging"&gt;Toolman Tim&lt;/a&gt; and &lt;a href="http://snippets.dzone.com/posts/show/4371"&gt;Dzone Snippets&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;~/.irbrc&lt;/h3&gt;


&lt;pre&gt;
require 'pp'
require 'irb/completion'
ARGV.concat [ "--readline", "--prompt-mode", "simple" ]
IRB.conf[:AUTO_INDENT]=true

# load console_with_helpers if possible
script_console_running = ENV.include?('RAILS_ENV') &amp;&amp; IRB.conf[:LOAD_MODULES] &amp;&amp; IRB.conf[:LOAD_MODULES].include?('console_with_helpers')
rails_running = ENV.include?('RAILS_ENV') &amp;&amp; !(IRB.conf[:LOAD_MODULES] &amp;&amp; IRB.conf[:LOAD_MODULES].include?('console_with_helpers'))
irb_standalone_running = !script_console_running &amp;&amp; !rails_running

# log Rails stuff to STDOUT
if script_console_running
  require 'logger'
  Object.const_set(:RAILS_DEFAULT_LOGGER, Logger.new(STDOUT))
end

# Keep command-line history between startups
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history" 
&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; my friend &lt;a href="http://joannou.tumblr.com/"&gt;Joannou&lt;/a&gt; pointed out &lt;a href="http://utilitybelt.rubyforge.org/"&gt;Utility Belt&lt;/a&gt; which looks pretty nice also.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update 2 (a month later)&lt;/strong&gt;: Been using Utility Belt for a while and noticed some problems… it has a tendency to conflict with ActiveRecord validations and trigger bogus errors during callbacks. Also seems to destroy some of the init process with certain plugins like ActiveScaffold. Perhaps it’s too clever. I ended up rolling back to my old .irbc – &lt;span class="caps"&gt;YMMV&lt;/span&gt;.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/8hPkRll_AWY" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2007/12/23/my-irbrc</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2007-07-28:40</id>
    <published>2007-07-28T13:32:00Z</published>
    <updated>2009-10-12T14:39:31Z</updated>
    <category term="code" />
    <category term="ruby" />
    <category term="sound" />
    <category term="testing" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/KeXnobT-2dA/autotest-sound-effects" rel="alternate" type="text/html" />
    <title>Autotest: Now, With Sound Effects!</title>
<content type="html">
            &lt;p&gt;Update April 9, 2008: Ken Collins has released a &lt;a href="http://www.metaskills.net/2008/4/6/autotest-playlist-for-red-green-feedback"&gt;new version of the sound plugin with playlist support&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;

	&lt;p&gt;We’ve all been enjoying &lt;strong&gt;autotest&lt;/strong&gt;, part of the &lt;a href="http://www.zenspider.com/ZSS/Products/ZenTest"&gt;ZenTest&lt;/a&gt; gem. If you’ve tricked out your kit, then you have &lt;a href="http://ph7spot.com/articles/getting_started_with_autotest"&gt;plugins&lt;/a&gt; configured, so at minimum you’re &lt;a href="http://www.ridaalbarazi.com/blog/2007/04/05/autotest-growling-in-red-green/"&gt;red, green and growling&lt;/a&gt;.
Now, things get really fun.&lt;/p&gt;


&lt;blockquote&gt;&lt;a href="/static/autotest-sound10.html"&gt;Watch a screencast of autotest running with sound effects&lt;/a&gt;&lt;/blockquote&gt;

	&lt;p&gt;I’m stoked to announce the &lt;strong&gt;sound plugin for autotest&lt;/strong&gt;. This simple chunk of code will fire off sounds for different events in autotest. I’ve provided a set of custom-made sounds, produced with my trusty &lt;a href="http://www.clavia.se/products/nordmodular/models.htm"&gt;Nord Modular&lt;/a&gt; synthesizer and fine-tuned for an optimal testing experience. You should be able to use these all day without annoying your neighbors too much.&lt;/p&gt;


	&lt;p&gt;Here’s what you need to do:&lt;/p&gt;


	&lt;h3&gt;1. Install mgp321&lt;/h3&gt;


in &lt;span class="caps"&gt;OS X&lt;/span&gt;:
&lt;pre&gt;$ sudo port install mpg321&lt;/pre&gt;

for Linux:
&lt;pre&gt;$ sudo apt-get install mpg321&lt;/pre&gt;

	&lt;h3&gt;2. Download and extract the plugin&lt;/h3&gt;


	&lt;p&gt;The starter sound fx are in the zip file. Extract it in your home directory, it will create ~/autotest/sound.&lt;/p&gt;


	&lt;p&gt;&lt;img src="/static/pdf.gif" alt="" /&gt; &lt;a href="/static/autotest-sound-1_2.zip"&gt;autotest-sound-1_2.zip&lt;/a&gt; (86k)&lt;/p&gt;


	&lt;h3&gt;3. Configure your ~/.autotest file:&lt;/h3&gt;


&lt;pre&gt;
require '~/autotest/sound/sound.rb'
Autotest::Sound.sound_path = "~/autotest/sound/sound_fx/" 
&lt;/pre&gt;

	&lt;h3&gt;Enjoy &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt;&lt;/a&gt; with audio feedback!&lt;/h3&gt;


	&lt;p&gt;I’ve been using this setup for several weeks now. I initially wrote it as a gag, but I have since found it to be incredibly useful. It’s nice know what your testing status via audio – you don’t have to switch windows or take your eyes off the code. I’ve even turned off Growl, I don’t need it any more. audio makes testing more fun. :)&lt;/p&gt;


	&lt;p&gt;If there are any problems or feedback, please post a comment here.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt;Plugin instructions and zip file updated, now with Windows support. Thanks, John and Jamie.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt; #2:&lt;/strong&gt;Fixed bad path in instructions and doc fixes in zip file. (thanks, Matt)&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/KeXnobT-2dA" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2007/7/28/autotest-sound-effects</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2007-06-01:31</id>
    <published>2007-06-01T11:50:00Z</published>
    <updated>2007-06-06T15:59:58Z</updated>
    <link href="http://feedproxy.google.com/~r/fozworks/~3/hyt-Jfh1SnY/how-to-fix-fixtures" rel="alternate" type="text/html" />
    <title>Healthy Migrations</title>
<content type="html">
            &lt;p&gt;Continuing with the &lt;a href="/2007/5/23/validating-fixtures"&gt;fixtures/test theme&lt;/a&gt;, I want to focus on the place where fixtures actually live – the database. Migrations are the blueprint, however, they often break and we don’t notice. You should alway be able to do this:&lt;/p&gt;


&lt;pre&gt;
$ rake db:migrate VERSION=0
$ rake db:migrate
&lt;/pre&gt;

	&lt;p&gt;I used to say “what does it matter? We’re never going back to migration 3, we’re on 156 now!” This kind of thinking showed how I didn’t understand the &lt;strong&gt;usefulness&lt;/strong&gt; of migrations:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Setting up a new development system should not require a recent database snapshot. &lt;/li&gt;
		&lt;li&gt;Automated tests and build notifications are simpler when the migrations are clean.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;cap rollback&lt;/strong&gt; will save your life some day&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Migrations are not just a historical record of your database design. They instead give you a way to build your database up from scratch, doing more than just creating a schema. You can seed data, create indexes, and make transformations.&lt;/p&gt;


	&lt;p&gt;When you first start a rails project, and everything is golden, migrations are easy. Eventually, you run into problems. It happens a lot, because we typically don’t test the entire migration sequence. For example:&lt;/p&gt;


	&lt;h4&gt;A model changes somewhere, and breaks a dependent migration&lt;/h4&gt;


	&lt;p&gt;Using models in migrations is a common way to seed the database, or manipulate things:&lt;/p&gt;


&lt;pre&gt;
class CreateNewsSection &amp;lt; ActiveRecord::Migration
  def self.up
    Section.create(:name =&amp;gt; 'news', :title=&amp;gt;"News")
  end

  def self.down
    Section.find_by_name('news').destroy
  end
end
&lt;/pre&gt;

	&lt;p&gt;If you delete or refactor the Section model later, this migration will likely break. The &lt;a href="http://toolmantim.com/article/2006/2/23/migrating_with_models"&gt;solution for this one&lt;/a&gt; is to define the model in the migration:&lt;/p&gt;


&lt;pre&gt;
class CreateNewsSection &amp;lt; ActiveRecord::Migration
  class Section &amp;lt; ActiveRecord::Base; end
  def self.up
    Section.create(:name =&amp;gt; 'news', :title=&amp;gt;"News")
  end
  ... etc.  
&lt;/pre&gt;

	&lt;h4&gt;Someone on the team checks in a migration that has a bug&lt;/h4&gt;


	&lt;p&gt;If the problem is trivial, they might be tempted to skip reporting it and just fix it in the database to keep things moving. Or, they may not even notice the problem, depending on &lt;strong&gt;when&lt;/strong&gt; they updated. These issues can lead to inconsistencies, and tests that pass for one developer, but not another!&lt;/p&gt;


	&lt;h4&gt;Developers only migrate up&lt;/h4&gt;


	&lt;p&gt;Migrating down should work too, what if you need to roll back to fix something in production? Always write a sensible down method and test it. It does not have to perfectly reverse the database, it just needs to return it to a state that will enable the previous migration to run it’s down method. I’ve seen horrific migrations checked in like this:&lt;/p&gt;


&lt;pre&gt;
  def self.down
    # no need to do this
  end
&lt;/pre&gt;

	&lt;h4&gt;The team works from a production db snapshot based on a deployed site&lt;/h4&gt;


	&lt;p&gt;This is bad, because it means the team is probably not using &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt;&lt;/a&gt;, and are instead relying on browser interaction to develop the app. At minimum, they are blind to migration issues. Relying on an external database for development is an unwise dependency. It also complicates setup for testing.&lt;/p&gt;


	&lt;h3&gt;Keep Migrations Working!&lt;/h3&gt;


	&lt;p&gt;Each time you add a migration, or refactor a number models, you should check that  &lt;strong&gt;all&lt;/strong&gt; the migrations are working. There are a number of solutions for doing this – the most obvious is to drop the dev db and migrate up from scratch, see if it works.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://errtheblog.com/post/3"&gt;Err the blog&lt;/a&gt; posted a task a while back. There’s also this &lt;a href="http://snippets.dzone.com/posts/show/2031"&gt;often referenced snippet&lt;/a&gt; that works. And today, I noticed &lt;a href="http://ryandaigle.com/articles/2007/5/29/what-s-new-in-edge-rails-new-database-rake-tasks"&gt;this post on Ryan’s Scraps&lt;/a&gt;—it looks like Rails itself now has &lt;a href="http://dev.rubyonrails.org/changeset/6849"&gt;a task to do this&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;However, my favorite solution at the moment is sitting in a &lt;a href="http://dev.rubyonrails.org/ticket/8389"&gt;patch #8389&lt;/a&gt; (not committed at this date), which offers this bit of sugar:&lt;/p&gt;


&lt;pre&gt;
# in config/environment.rb:
config.active_record.schema_format = :migrations
&lt;/pre&gt;

	&lt;p&gt;This setting would force rails to build the database schema from migrations, not from sql or db/schema.rb. This simple solution seems elegant, and I hope it gets committed to core!&lt;/p&gt;


	&lt;p&gt;So before you check in migrations, make sure you can run them up from scratch. And then, don’t forget to make sure &lt;a href="http://fozworks.com/2007/5/23/validating-fixtures"&gt;your fixtures are still valid&lt;/a&gt;, too!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/hyt-Jfh1SnY" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2007/6/1/how-to-fix-fixtures</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2007-05-23:32</id>
    <published>2007-05-23T07:43:00Z</published>
    <updated>2007-05-23T13:37:26Z</updated>
    <category term="rails" />
    <category term="testing" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/xaLZ1ZwMpq0/validating-fixtures" rel="alternate" type="text/html" />
    <title>Validating Fixtures</title>
<content type="html">
            &lt;h2&gt;Fixtures Are Painful&lt;/h2&gt;


	&lt;p&gt;I just got back from RailsConf 2007, it was a brain-expanding conference. I spent a lot of time talking to Rails coders about how they do testing and use fixtures. I saw some patterns emerge. Generally, people agree that fixtures are painful:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;referencing ids in the fixtures is annoying and prone to error&lt;/li&gt;
		&lt;li&gt;the lack of a grouping mechanism makes selecting them harder&lt;/li&gt;
		&lt;li&gt;fixtures get out of date with model changes&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I plan to do a few posts about fixtures in the next coming weeks, to share some of what I have learned. For now, I’ll focus on validation.&lt;/p&gt;


	&lt;h2&gt;Fixtures Break&lt;/h2&gt;


	&lt;p&gt;The project I’m currently working on has a large number of fixtures (over 100 models). It’s become really hard to manage them all. Over time, some fixtures busted, and it became hard to diagnose random problems in tests.&lt;/p&gt;


	&lt;p&gt;We are fortunate to be working with &lt;a href="http://blog.zenspider.com/"&gt;zenspider&lt;/a&gt;, he’s helping us get our tests, dev process and performance in better shape. I complained a lot about invalid fixtures, and how I longed for a Rake task that could identify the broken ones. He offered up this:&lt;/p&gt;


&lt;pre&gt;
namespace :db do
  namespace :fixtures do
    task :validate =&amp;gt; :environment do
      name_map = Hash.new { |h,k| h[k] = k }

      Dir.chdir("app/models") do
        map = `grep set_table_name *.rb`.gsub(/[:\'\"]+|set_table_name/, '').split
        Hash[*map].each do |file, name|
          name_map[name] = file.sub(/\.rb$/, '')
        end
      end

      Dir["test/fixtures/*.yml"].each do |fixture|
        fixture = name_map[File.basename(fixture, ".yml")]

        begin
          klass = fixture.classify.constantize
          klass.find(:all).each do |thing|
            unless thing.valid? then
              puts "#{fixture}: id ##{thing.id} is invalid:" 
              thing.errors.full_messages.each do |msg|
                puts "   - #{msg}" 
              end
            end
          end
        rescue =&amp;gt; e
          puts "#{fixture}: skipping: #{e.message}" 
        end
      end
    end # validate
  end # fixtures
end # db
&lt;/pre&gt;

	&lt;p&gt;Put it in your project Rakefile, and you can then run:&lt;/p&gt;


&lt;pre&gt;
$ rake db:fixtures:validate
&lt;/pre&gt;

	&lt;p&gt;You will get back a list of all the fixtures that are not valid, with the validation messages.&lt;/p&gt;


	&lt;p&gt;But what about edge cases? What about “bad” form data? &lt;span class="caps"&gt;DHH&lt;/span&gt; has declared that &lt;a href="http://dev.rubyonrails.org/changeset/6227"&gt;most folks want all fixtures loaded&lt;/a&gt; at the start of the tests. The data in fixtures does not have to pass model validation before it is loaded into the db.&lt;/p&gt;


	&lt;p&gt;After discussing this with a number of folks, I’m starting to believe:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;All fixtures should be valid at all times&lt;/li&gt;
		&lt;li&gt;Fixtures should provide stuff required by your app to run tests (your admin user, default options, etc)&lt;/li&gt;
		&lt;li&gt;Edge cases should be created in tests, not fixtures &lt;/li&gt;
		&lt;li&gt;Test invalid data by loading a good fixture and changing it&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Rake db:fixtures:validate is helpful for keeping them valid. I plan to use it whenever I do a migration, just to ensure that nothing got broken.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/xaLZ1ZwMpq0" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2007/5/23/validating-fixtures</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2007-05-16:30</id>
    <published>2007-05-16T07:08:00Z</published>
    <updated>2007-05-16T07:09:18Z</updated>
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/Bs0JyGmQNzQ/railsconf-2007" rel="alternate" type="text/html" />
    <title>RailsConf 2007</title>
<content type="html">
            &lt;p&gt;Heading out to Portland tomorrow, I’m very excited. There are a whole lot of great presentations this year. Here’s what &lt;a href="http://myconfplan.com/users/somebox/conferences/RailsConf2007"&gt;I plan to see&lt;/a&gt;.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/Bs0JyGmQNzQ" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2007/5/16/railsconf-2007</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2007-04-16:29</id>
    <published>2007-04-16T06:48:00Z</published>
    <updated>2007-04-16T06:49:09Z</updated>
    <category term="rails" />
    <category term="testing" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/cy_dv5WCfTI/rake-task-to-run-a-custom-group-of-tests" rel="alternate" type="text/html" />
    <title>Rake task to run a custom group of tests</title>
<content type="html">
            &lt;p&gt;I have not really been getting into blogging yet, obviously. It’s been several months since the most recent post. I’m in New York at the moment, getting ready to launch a rails web project. More details about that later.&lt;/p&gt;


	&lt;p&gt;For now, I just had to post something I did recently that was handy: Using rake to run a specific group of files.&lt;/p&gt;


	&lt;p&gt;There are some great built-in tasks provided by Rake. Let’s look at the testing-related ones (run ‘rake -T’ to see them all):&lt;/p&gt;


&lt;pre&gt;
rake test:functionals               # Run the functional tests in test/functional
rake test:integration               # Run the integration tests in test/integration
rake test:plugins                   # Run the plugin tests in vendor/plugins/*/**/test (or specify with PLUGIN=name)
rake test:recent                    # Test recent changes
rake test:uncommitted               # Test changes since last checkin (only Subversion)
rake test:units                     # Run the unit tests in test/unit
&lt;/pre&gt;

	&lt;p&gt;These are all very useful. But on the site I’m currently working on, I wanted to run a set of tests that were related to a &lt;em&gt;section&lt;/em&gt; of the web site: the web store. I wanted to be able to run a specific combination of unit, functional, and integration tests.&lt;/p&gt;


	&lt;p&gt;I looked at the source for the tasks that rails provides for rake. The testing tasks are defined in lib/tasks/testing.rake in the rails distribution. The code for the unit testing task, for example:&lt;/p&gt;


&lt;pre&gt;
  desc "Run the unit tests in test/unit" 
  Rake::TestTask.new(:units =&amp;gt; "db:test:prepare") do |t|
    t.libs &amp;lt;&amp;lt; "test" 
    t.pattern = 'test/unit/**/*_test.rb'
    t.verbose = true
  end
&lt;/pre&gt;

	&lt;p&gt;The files are specified as a glob. But, I did not want to use a file pattern. I consulted the &lt;a href="http://rake.rubyforge.org/"&gt;rake &lt;span class="caps"&gt;API&lt;/span&gt; docs&lt;/a&gt; and discovered the &lt;strong&gt;test_files=&lt;/strong&gt; setter method of &lt;a href="http://rake.rubyforge.org/classes/Rake/TestTask.html"&gt;Rake::TestTask&lt;/a&gt;. Here’s what I ended up with:&lt;/p&gt;


&lt;pre&gt;
namespace :test do
  tests = []
  tests &amp;lt;&amp;lt; "test/integration/store_test.rb" 
  # models
  %w(product product_category product_categorization product_option product_option_value 
    line_item cart order shipment).each do |file|
      tests &amp;lt;&amp;lt; "test/unit/#{file}_test.rb" 
  end
  # controllers
  %w(cart checkout store).each do |file|
    tests &amp;lt;&amp;lt; "test/functional/#{file}_controller_test.rb" 
  end
  # admin controllers
  %w(products product_option_values product_options orders).each do |file|
    tests &amp;lt;&amp;lt; "test/functional/admin/#{file}_controller_test.rb" 
  end
  Rake::TestTask.new(:store =&amp;gt; "db:test:prepare") do |t|
    t.libs &amp;lt;&amp;lt; "test" 
    t.test_files = tests
    t.verbose = true
  end
  Rake::Task['test:store'].comment = "Run the store-related tests" 
end
&lt;/pre&gt;

	&lt;p&gt;I saved this task in lib/tasks/store_tests.rake under my project directory. Now, I can do this:&lt;/p&gt;


&lt;pre&gt;
$ rake test:store
(in ~/rails_project)
/opt/local/bin/ruby -Ilib:test "/opt/local/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/rake/rake_test_loader.rb" "test/integration/store_test.rb" "test/unit/product_test.rb" "test/unit/product_category_test.rb" "test/unit/product_categorization_test.rb"  [... etc ...]
Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/rake/rake_test_loader
Started
....................................................................
Finished in 10.799886 seconds.

68 tests, 682 assertions, 0 failures, 0 errors
&lt;/pre&gt;

	&lt;p&gt;All the store tests are run as a group. This is a nice way to verify that things are working in the money-making part of the site.&lt;/p&gt;


	&lt;p&gt;However, I have to remember to update the task whenever I refactor or make additions. I’m thinking about symbolic links, now. Perhaps the tests could be grouped together in a directory (like test/groups/store) by making symbolic links to them in there. And, subversion deals with symlinks well…&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/cy_dv5WCfTI" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2007/4/16/rake-task-to-run-a-custom-group-of-tests</feedburner:origLink></entry>
  <entry xml:base="http://www.fozworks.com/">
    <author>
      <name>foz</name>
    </author>
    <id>tag:www.fozworks.com,2006-12-18:12</id>
    <published>2006-12-18T01:14:00Z</published>
    <updated>2008-05-01T17:05:48Z</updated>
    <category term="code" />
    <link href="http://feedproxy.google.com/~r/fozworks/~3/4UNOxQk8q0E/wymeditor" rel="alternate" type="text/html" />
    <title>WYMeditor</title>
<summary type="html">&lt;p&gt;I’ve been looking for a great javascript/css editor for a long time. I have tried out several of them, but I was turned off by how busy and complicated they seemed. Too many icons, or not css-centric. A site with a clean &lt;span class="caps"&gt;CSS&lt;/span&gt; design can get easily bungled by badly formated content.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I’ve been looking for a great javascript/css editor for a long time. I have tried out several of them, but I was turned off by how busy and complicated they seemed. Too many icons, or not css-centric. A site with a clean &lt;span class="caps"&gt;CSS&lt;/span&gt; design can get easily bungled by badly formated content.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.wymeditor.org/en/"&gt;&lt;img src="http://www.fozworks.com/assets/2006/12/18/wymeditor.gif" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I’ve been looking for a great javascript/css editor for a long time. I have tried out several of them, but I was turned off by how busy and complicated they seemed. Too many icons, or not css-centric. A site with a clean &lt;span class="caps"&gt;CSS&lt;/span&gt; design can get easily bungled by badly formated content.&lt;/p&gt;


	&lt;p&gt;I was fortunate to meet &lt;a href="http://www.peterkrantz.com/"&gt;Peter Krantz&lt;/a&gt; at &lt;a href="http://railsconf.org"&gt;Railsconf 2006&lt;/a&gt;. Peter runs the &lt;a href="http://www.standards-schmandards.com"&gt;Standards-Schmandards&lt;/a&gt; website, which I have been following for years. He recently &lt;a href="http://www.standards-schmandards.com/2006/wysiwym/"&gt;posted about&lt;/a&gt; &lt;a href="http://www.wymeditor.org/en/"&gt;WYSiwym&lt;/a&gt;, a visual editor built in javascript that uses pure css to power a creative approach to the problem of web-based rich text editing. Take a minute to check out &lt;a href="http://demo.wymeditor.org/editor/editor.htm"&gt;the demo&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I believe this project has a bright future. Web-based rich text editing should respect the &lt;span class="caps"&gt;CSS&lt;/span&gt; rules put in place by the site’s designers. Less is more when it comes to formatting, and the “block-based” approach to formatting makes a lot of sense for most rich text web applications. I definitely plan to try this out on my next &lt;span class="caps"&gt;CMS&lt;/span&gt; project!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/fozworks/~4/4UNOxQk8q0E" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://www.fozworks.com/2006/12/18/wymeditor</feedburner:origLink></entry>
</feed>
