<?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>LRBlog &#187; Ruby on Rails</title>
	<atom:link href="http://blog.lrdesign.com/category/development/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.lrdesign.com</link>
	<description>Logical Reality Design: Web Design and Software Development</description>
	<lastBuildDate>Thu, 08 Jul 2010 01:40:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Convection: self-hosted secure file exchange in Rails</title>
		<link>http://blog.lrdesign.com/2010/06/convection-self-hosted-secure-file-exchange-in-rails/</link>
		<comments>http://blog.lrdesign.com/2010/06/convection-self-hosted-secure-file-exchange-in-rails/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 02:54:03 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[File Exchange]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[client management]]></category>
		<category><![CDATA[file upload]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=160</guid>
		<description><![CDATA[Need to swap files with clients or collaborators, but don't want to (or can't) trust those files to Amazon or sendbigfiles.com?  Want fine-grained control over which users can see which files?   Try Convection.]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.lrdesign.com/wp-content/uploads/2010/06/convection.png"><img src="http://blog.lrdesign.com/wp-content/uploads/2010/06/convection.png" alt="" title="convection" width="100" height="100" class="alignleft size-full wp-image-166" style="margin-right: 1em;" /></a>Introducing <a href="http://github.com/LRDesign/Convection">Convection</a>, an open-source (MIT License) project of Logical Reality Design.    Need to swap files with clients or collaborators, but don't want to (or can't) trust those files to Amazon or sendbigfiles.com?  Want fine-grained control over which users can see which files?   Try Convection.</p>
<p>Lots of file exchange services exist, for example SendBigFiles.com etc.  However, all of these services are hosted on someone else's hardware, and most of them share files by transferring URLs -- usually via email -- without good access control or authorization schemes. </p>
<p>We built Convection because a client needed to transfer files with other companies, but they needed to host the system themselves because the contracts they hold with their own clients require them not to store data on services that they don't control.   The specifications Convection was built around were:</p>
<ol>
<li>Hosted on our own server.</li>
<li>Downloads require a login, and files cannot be shared by email.</li>
<li>Users must log in to download files or see available files.</li>
<li>User accounts can be grouped, groups can be managed.</li>
<li>Files can be shared with an entire group.</li>
<li>Files uploaded by users default to minimal permission - visible only to the uploader and to admins.</li>
<li>All communications over SSL. (we made this optional)</li>
</ol>
<h2>Installing and hosting Convection</h2>
<p>To run Convection, you will need a webserver capable of running a Ruby on Rails application, and a database.   Setting such a thing up is beyond the scope of this post.   If you have a Dreamhost account, you can set up a Rails-capable domain with a couple of clicks in their web panel.  In addition to the server, you will need to set up a database (we have only tested MySQL, but Convection should work with any SQL database for which Rails/ActiveRecord has a supported adapter, including PostgreSQL and Oracle), and initialize the database with these two commands:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">&gt;</span> rake db:migrate <span style="color: #007800;">RAILS_ENV</span>=production
  <span style="color: #000000; font-weight: bold;">&gt;</span> rake db:seed <span style="color: #007800;">RAILS_ENV</span>=production</pre></div></div>

<p>This will generate the tables necessary for Convection to run, and create a pair of initial demo users "admin" and "user", both with password "foobar".   </p>
<p>If you are setting up a server yourself, there are plenty of guides to deploying Rails on the web.   Much of our own <a href="http://blog.lrdesign.com/2010/02/howto-setting-up-cruisecontrol-rb-on-slicehost/">guide to deploying CruiseControl.rb</a> can be used to set up any Rails application on Slicehost or any other Ubuntu Linux hosting provider.  </p>
<p>Let me know if you're trying to deploy Convection and having trouble: if we know people are using it we may put effort into making it easier to deploy and install, and write a more thorough guide.</p>
<p>A few other links that may help you with deploying a Rails application, depending on your environment:</p>
<ol>
<li><a href="http://wdvl.com/Authoring/ror/Passenger/saurabh_bhatia04142010.html">Using Phusion Passenger to Deploy a Rails Application on Apache</a></li>
<li><a href="http://pragprog.com/titles/fr_deploy/deploying-rails-applications">Deploying Rails Applications (book)</a></li>
</ol>
<p>If you Google around you may find plenty of other links relevant to your particular environment.</p>
<h2>Configuring Convection</h2>
<p>If you log into your running Convection application as an administrator (initial user "admin", password "foobar"), an Admin Tools utility will appear in the right hand column.   From here, you can access tools for creating users, and groups, and the general site configuration.</p>
<p>In general site config, you can set your site name and logo, set whether or not the site requires SSL access (Note: your server must already support SSL!) outgoing email and email notification preferences, add Google analytics, and an assortment of other site configuration operations that are mostly self-explanatory. </p>
<h2>Upload progress bar: experimental feature.</h2>
<p>If your site hosts large uploads that take a while to transfer, you can try our experimental tools to provide an upload progress bar to the user.   This tool will only work if your site is served by Apache, and requires installing and configuring an optional module for Apache.</p>
<p>To enable this tool, follow the instructions in the README file and associated links, and turn on the progress bar setting in site preferences.</p>
<h2>Helping us improve Convection</h2>
<p>Convection is currently in version 1.1.4 and has been in production in two places (that we know of) for about five months as of June 8, 2010.   </p>
<p>Please let us know if you are using Convection and enjoy it (or don't).   Feel free to request features or alterations, but Convection is open source, so also please consider contributing if you have ideas!  </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2010/06/convection-self-hosted-secure-file-exchange-in-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transactional Testing for Multiple Databases in ActiveRecord</title>
		<link>http://blog.lrdesign.com/2010/03/transactional-testing-for-multiple-databases-in-activerecord/</link>
		<comments>http://blog.lrdesign.com/2010/03/transactional-testing-for-multiple-databases-in-activerecord/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 06:36:27 +0000</pubDate>
		<dc:creator>Judson</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=130</guid>
		<description><![CDATA[We've been working on an app that needs to stand astride two databases - one local DB for the app itself, and another with restrictive policies about modifications that is nonetheless authoritative on many subjects. There's a fair amount of tricky interaction between the two, and testing has been a delightful challenge. We're using the [...]]]></description>
			<content:encoded><![CDATA[<p>We've been working on an app that needs to stand astride two databases - one local DB for the app itself, and another with restrictive policies about modifications that is nonetheless authoritative on many subjects.  There's a fair amount of tricky interaction between the two, and testing has been a delightful challenge.</p>
<p>We're using the use_db plugin, and all it takes to make testing transactions happen around multiple DBs is:</p>
<p><code>In: spec/spec_helper.rb</code></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'override_test_callbacks'</span></pre></div></div>

<p>My concern comes from the fact that this is a direct and unfiltered monkeypatch on ActiveRecord::TestFixtures.  So it relies on <code>use_transactional_fixtures</code> (which could certainly be used without using actual fixures, granted), and if the test transaction code moves within Rails, that's another integration to worry about.  Or if we add a spec that doesn't wind up making ActiveRecord::TestFixtures load... Or if we decide to use something other than use_db...</p>
<p>So instead I'm using:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">Spec::Runner</span>.<span style="color:#9900CC;">configure</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>config<span style="color:#006600; font-weight:bold;">|</span>
  config.<span style="color:#9900CC;">prepend_before</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#006600; font-weight:bold;">&#40;</span>UseDbPlugin.<span style="color:#9900CC;">all_use_dbs</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>db<span style="color:#006600; font-weight:bold;">|</span>
      db.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">increment_open_transactions</span>
      db.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">transaction_joinable</span> = <span style="color:#0000FF; font-weight:bold;">false</span>
      db.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">begin_db_transaction</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  config.<span style="color:#9900CC;">append_after</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#006600; font-weight:bold;">&#40;</span>UseDbPlugin.<span style="color:#9900CC;">all_use_dbs</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">reverse</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>db<span style="color:#006600; font-weight:bold;">|</span>
      db.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">rollback_db_transaction</span>
      db.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">decrement_open_transactions</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>If we weren't already using transactional fixtures, I might pull out the <code lang="ruby">- [ActiveRecord::Base]</code>.  And if we were to change off of use_db, there's one place to change the transaction code.  Finally, there's much less dependence on the innards of ActiveRecord - only it's published API.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2010/03/transactional-testing-for-multiple-databases-in-activerecord/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Danger: ActiveRecord, param hashes, and symbol keys</title>
		<link>http://blog.lrdesign.com/2010/03/danger-activerecord-param-hashes-and-symbol-keys/</link>
		<comments>http://blog.lrdesign.com/2010/03/danger-activerecord-param-hashes-and-symbol-keys/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 22:20:17 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=109</guid>
		<description><![CDATA[Here's a little foible of ActiveRecord that cost me over an hour today. AR accepts both symbol keys and string keys when specifying attributes. Both of these are valid ways of mass assigning attributes to a Rails model: MyModel.new&#40;:field_1 =&#62; 'foo', :field_2 =&#62; 'bar'&#41; MyModel.new&#40;'field_1' =&#62; 'foo', 'field_2' =&#62; 'bar'&#41; It's convenient, often, to not [...]]]></description>
			<content:encoded><![CDATA[<p>Here's a little foible of ActiveRecord that cost me over an hour today.   AR accepts both symbol keys and string keys when specifying attributes.   Both of these are valid ways of mass assigning attributes to a Rails model:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">MyModel.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:field_1</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'foo'</span>, <span style="color:#ff3333; font-weight:bold;">:field_2</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'bar'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
MyModel.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'field_1'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'foo'</span>, <span style="color:#996600;">'field_2'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'bar'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>It's convenient, often, to not have to worry about whether your keys are symbols are strings since they get converted around a bit when you pass parameters.   The downside of this, however, is that it will happily accept BOTH without complaining, and will quietly default to the symbol key regardless of the order you specify them in:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> model = MyModel.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:field_1</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'foo'</span>, <span style="color:#996600;">'field_1'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'bar'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#0000FF; font-weight:bold;">nil</span>; 
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> mymodel.<span style="color:#9900CC;">field_1</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'foo'</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> model = MyModel.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'field_1'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'foo'</span>, <span style="color:#ff3333; font-weight:bold;">:field_1</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'bar'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#0000FF; font-weight:bold;">nil</span>;
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> mymodel.<span style="color:#9900CC;">field_1</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'bar'</span></pre></div></div>

<h3>Okay, so that's kinda sloppy.  Bad ActiveRecord!  No Biscuit!</h3>
<p>This can cause <em>serious</em> confusion for the unwary.   When ActionController hands us a params hash, it always has String keys, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#CC0066; font-weight:bold;">eval</span> params
<span style="color:#006600; font-weight:bold;">=&gt;</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'article'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'title'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Awesome blog post'</span>, <span style="color:#996600;">'body'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'I will make you smart'</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>But most of us, canonically, specify params and default AR values with symbols, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">   post <span style="color:#ff3333; font-weight:bold;">:article</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:title <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Awesome blog post'</span>, <span style="color:#ff3333; font-weight:bold;">:body</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'I will make you smart'</span><span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>So we get used to thinking about them as symbols.</p>
<p>This means we can make mistakes like this one I made recently.   Consider this block of code for a shopping cart model that pre-fills some fields for an associated Payment by pulling the address from the user's profile, to save the user re-typing their address:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ShoppingCart <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_one <span style="color:#ff3333; font-weight:bold;">:payment</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> build_default_payment<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
    <span style="color:#008000; font-style:italic;">#prepopulate the billing address from the profile and merge</span>
    <span style="color:#008000; font-style:italic;">#with params passed into options</span>
    build_payment<span style="color:#006600; font-weight:bold;">&#40;</span>prepopulated_fields.<span style="color:#9900CC;">merge</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>    
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> prepopulated_fields
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>addr = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">person</span>.<span style="color:#9900CC;">address</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#ff3333; font-weight:bold;">:billing_address_1</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> addr.<span style="color:#9900CC;">line_1</span>,
        <span style="color:#ff3333; font-weight:bold;">:billing_address_2</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> addr.<span style="color:#9900CC;">line_2</span>,
        <span style="color:#ff3333; font-weight:bold;">:city</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> addr.<span style="color:#9900CC;">city</span>,
        <span style="color:#ff3333; font-weight:bold;">:state</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> addr.<span style="color:#9900CC;">state</span>,
        <span style="color:#ff3333; font-weight:bold;">:zip</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> addr.<span style="color:#9900CC;">zipcode</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Looks great, right?  And if the user's address has a nil field (like no city, or no line_1), it will get overwritten by the hash merge.</p>
<p>Except not.  I specified symbol keys in prepopulated_fields, but the hash getting passed to build_default_payment's 'options' argument has string keys, because it's coming from params.  So the merge doesn't overwrite the value for :line_1, it simply adds a new key 'line_1'.  So, if a user has a profile address but hadn't entered a line_1 (just city and state), and then manually entered line_1 in the payment form to submit, the Payment build during the create action was getting this hash:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">build_payment<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#123;</span>
   <span style="color:#ff3333; font-weight:bold;">:line_1</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">nil</span>,
   <span style="color:#ff3333; font-weight:bold;">:city</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Pasadena'</span>,
   <span style="color:#ff3333; font-weight:bold;">:state</span> <span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">'CA'</span>,
   <span style="color:#ff3333; font-weight:bold;">:zipcode</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'91106'</span>
   <span style="color:#996600;">'line_1'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'100 Main St.'</span>.
<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>ActiveRecord was respecting the :line_1 => nil from the profile, and not the 'line_1' => '100 Main St.' from params.  This meant that the user couldn't make payment!  The payment had validates_inclusion_of line_1, and even though it was typed into the form it was getting ignored because of the nil from his profile address.   Very frustrating for a user to manually type in a billing address and get back "Address Line 1 can't be blank." on every submit!</p>
<p>Nasty ... this one took a while to figure out.   Beware of this little foible of ActiveRecord!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2010/03/danger-activerecord-param-hashes-and-symbol-keys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RailsTutorial.org launched</title>
		<link>http://blog.lrdesign.com/2009/12/railstutorial-org-launched/</link>
		<comments>http://blog.lrdesign.com/2009/12/railstutorial-org-launched/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 18:56:28 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=83</guid>
		<description><![CDATA[The new Ruby on Rails Tutorial book and website by Michael Hartl has launched at RailsTutorial.org.   Hartl is the author of RailsSpace and cofounder of the Insoshi Ruby on Rails social networking platform. Logical Reality did the logo and layout design work for Rails Tutorial. &#160;]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-medium wp-image-84" title="rails-tutorial-logo-2" src="http://blog.lrdesign.com/wp-content/uploads/2009/12/rails-tutorial-logo-2-300x251.png" alt="rails-tutorial-logo-2" width="300" height="251" />The new <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial book</a> and website by Michael Hartl has launched at <a href="http://railstutorial.org/">RailsTutorial.org</a>.   Hartl is the author of RailsSpace and cofounder of the Insoshi Ruby on Rails social networking platform.</p>
<p>Logical Reality did the logo and layout design work for Rails Tutorial.</p>
<div style="clear: both;">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2009/12/railstutorial-org-launched/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using link_to (or other helper methods) in a controller</title>
		<link>http://blog.lrdesign.com/2009/05/using-link_to-or-other-helper-methods-in-a-controller/</link>
		<comments>http://blog.lrdesign.com/2009/05/using-link_to-or-other-helper-methods-in-a-controller/#comments</comments>
		<pubDate>Wed, 06 May 2009 23:40:10 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[controllers]]></category>
		<category><![CDATA[helper methods]]></category>
		<category><![CDATA[link_to]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=57</guid>
		<description><![CDATA[This one was a big aggravator to me lately. I have one controller that needs to call link_to and url_for, which are normally helper methods you'd call from a view. However, in this case during certain modifications to a record, I actually need to append user-visible HTML links to a block of HTML stored in [...]]]></description>
			<content:encoded><![CDATA[<p>This one was a big aggravator to me lately.   I have one controller that needs to call link_to and url_for, which are normally helper methods you'd call from a view.   However, in this case during certain modifications to a record, I actually need to append user-visible HTML links to a block of HTML stored in that object, or possibly another one.</p>
<p>Specifically, I needed to put annotations in the description of a work order object that said, for example "this work order was escalated from <a href="/tasks/293">Problem Report 293</a>.   This was done in a create action that redirected at the end and never rendered a view, so I really did need to generate that link in the controller.   And for consistency with the rest of the application, I wanted to generate the link with link_to(@task).</p>
<p>Now, ActionView::Helpers::UrlHelper is not loaded in a Rails controller, even if you've put helper :all in application.rb (application_controller.rb in newer versions).   So, when I tried to use link_to in the controller, I got an error:</p>
<p><code>NoMethodError: undefined method `link_to' for #<br />
/Users/evan/Development/Ruby/eclipticdb/app/helpers/tasks_helper.rb:64:in `task_link'<br />
/Users/evan/Development/Ruby/eclipticdb/app/controllers/tasks_controller.rb:103:in `escalate'<br />
... etc ...<br />
</code></p>
<h2>The first fix - but with a problem</h2>
<p>A year ago, I fixed this just by adding <code>include ActionView::Helpers::UrlHelper</code> at the top of that controller.  This worked great ... for a while.</p>
<p>Lately, I've been rewriting this application into a RESTful style - it had previously been a controller/action style application.  In the process, I started linking things with resource paths and polymorphic paths ... a lot of <code>link_to @task</code> and <code>edit_polymorphic_path(@task)</code> sorts of bits.   And these started breaking.   I began seeing this mysterious error:</p>
<h4>Error:</h4>
<p><code>You have a nil object when you didn't expect it!<br />
The error occurred while evaluating nil.url_for</p>
<p>... some code here that calls a link_to ...</p>
<p>Trace of template inclusion: /tasks/_task_panel.html.erb, /tasks/_task_tabbed_panel.html.erb, /tasks/index.html.erb</p>
<p>RAILS_ROOT: /Users/evan/Development/Ruby/eclipticdb<br />
Application Trace | Framework Trace | Full Trace</p>
<p>vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb:71:in `send'<br />
vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb:71:in `url_for'</code></p>
<p>This one was a real bitch to debug, I have to say.   The line in question that was failing in url_helper.rb said this: <code>url = @controller.send(:url_for, options)</code>.   Clearly, @controller was nil ... which was very bizarre, because I never interact with that instance variable anywhere.</p>
<p>I thrashed around trying to find the cause of this error for quite some time.  Eventually I realized that the link_to method was only failing when called from a view in TasksController, and not from any other controller.  And then I realized that TasksController was the one where, a year ago, I'd put <code>include ActionView::Helpers::UrlHelper</code> at the top.   Somehow, including that helper in the controller was nullifying <code>@controller</code> when those helper method we called from within the view.   I removed the include and my polymorphic and resource links all started working again.</p>
<h2>Now back to the original problem!</h2>
<p>Of course, that then left me back with the problem I'd had a year ago ... needing to use link_to from within the controller and having no way to do it.   After a fair bit of googling around I found <a href="http://www.neeraj.name/blog/articles/740-using-helpers-in-controllers">this post</a> from Neeraj, which had an interesting approach -- but a commenter had suggested a much easier solution:</p>
<p>[sourcecode language='ror']self.class.helpers.link_to[/sourcecode]</p>
<p>I'm not certain where one would find this in the docs, but it does seem to have solved my problem for now.  Onward and upward!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2009/05/using-link_to-or-other-helper-methods-in-a-controller/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Single Table Inheritance and RESTful Routes</title>
		<link>http://blog.lrdesign.com/2009/03/single-table-inheritance-and-restful-routes/</link>
		<comments>http://blog.lrdesign.com/2009/03/single-table-inheritance-and-restful-routes/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 21:00:39 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[RESTful]]></category>
		<category><![CDATA[routes]]></category>
		<category><![CDATA[single table inheritance]]></category>
		<category><![CDATA[STI]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=52</guid>
		<description><![CDATA[I'm converting an old, controller/action/id style Rails application to a more RESTful way of doing things, and ran into a brief roadblock: one of my main tables uses single table inheritance to generate three subclasses of items. I never actually use the superclass "task", I only use the three subclasses "action item", "work order", and [...]]]></description>
			<content:encoded><![CDATA[<p>I'm converting an old, controller/action/id style Rails application to a more RESTful way of doing things, and ran into a brief roadblock:   one of my main tables uses single table inheritance to generate three subclasses of items.   I never actually use the superclass "task", I only use the three subclasses "action item", "work order", and "problem report".</p>
<p>So, I ran into this little challenge:  all three STI subclasses use the same controller, "tasks", because they all have essentially the same behavior and differ only in minor details.    But, when I do a resources map:</p>
<p><code>map.resources :tasks</code></p>
<p>Then I get errors in much of my code when I say things like <code>redirect_to @task</code>, because if that task happens to be an ActionItem, it's trying to call <code>action_item_path(@task)</code>, which doesn't exist.</p>
<p>I googled around a bit to no result.  Striking out on my own, it turns out the answer is as simple as mapping each resource independently, and just overriding the controller in map.resources:</p>
<h4>In config/routes.rb</h4>
<p><code>map.resources :tasks<br />
map.resources :action_items, :controller => 'tasks'<br />
map.resources :work_orders, :controller => 'tasks'<br />
map.resources :problem_reports, :controller => 'tasks'<br />
</code></p>
<p>Now, <code>redirect_to @task</code> works just fine regardless of which subclass <code>@task</code> happens to be.   </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2009/03/single-table-inheritance-and-restful-routes/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Bypassing mass assignment for update_attributes</title>
		<link>http://blog.lrdesign.com/2009/03/bypassing-mass-assignment-for-update_attributes/</link>
		<comments>http://blog.lrdesign.com/2009/03/bypassing-mass-assignment-for-update_attributes/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 21:45:05 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Active Record]]></category>
		<category><![CDATA[mass assignment]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[update_attributes]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=51</guid>
		<description><![CDATA[I've been following this excellent post by M. Hartl and this post by E. Chapweske banishing mass assignment from one of my Rails applications due to launch soon. I'm following Chapweske's approach of blocking mass assignment by default in all models, by putting this line in an initializer: ActiveRecord::Base.send(:attr_accessible, nil) This had the expected side [...]]]></description>
			<content:encoded><![CDATA[<p>I've been following <a href="http://blog.insoshi.com/2008/09/21/finding-and-fixing-mass-assignment-problems-in-rails-applications/#">this excellent post by M. Hartl</a> and <a href="http://railspikes.com/2008/9/22/is-your-rails-application-safe-from-mass-assignment">this post by E. Chapweske</a> banishing mass assignment from one of my Rails applications due to launch soon.</p>
<p>I'm following Chapweske's approach of blocking mass assignment by default in all models, by putting this line in an initializer:</p>
<p><code>ActiveRecord::Base.send(:attr_accessible, nil)</code></p>
<p>This had the expected side effect of breaking several zillion tests, because tests frequently use things like Model.build() and Model.create!() to generate on-demand fixtures during testing.  Hartl has a great bit of code that creates unsafe_build() and unsafe_create() methods in ActiveRecord.   You can use these methods instead of build() and create() to function as expected in your tests.</p>
<p>This works great, except that I also use the mass-assignment method update_attributes! in my tests and specs frequently, particularly when I want to spec the effect a change on one model has on an associated models' methods.   So, I expanded on Hartl's helper code a bit, to give myself the necessary methods.   In case it helps anyone else:</p>
<h4>/lib/initializers/unsafe_build_and_create.rb</h4>
<p><code>class ActiveRecord::Base</p>
<p>  # Build and create records unsafely, bypassing attr_accessible.<br />
  # These methods are especially useful in tests and in the console.</p>
<p>  def self.unsafe_build(attrs)<br />
    record = new<br />
    record.unsafe_attributes = attrs<br />
    record<br />
  end</p>
<p>  def self.unsafe_create(attrs)<br />
    record = unsafe_build(attrs)<br />
    record.save<br />
    record<br />
  end</p>
<p>  def self.unsafe_create!(attrs)<br />
    unsafe_build(attrs).save!<br />
  end</p>
<p>  def unsafe_update_attributes!(attrs)<br />
    self.unsafe_attributes = attrs<br />
    self.save!<br />
  end</p>
<p>  def unsafe_update_attributes(attrs)<br />
    self.unsafe_attributes = attrs<br />
    self.save<br />
  end</p>
<p>  def unsafe_attributes=(attrs)<br />
    attrs.each do |k, v|<br />
      send("#{k}=", v)<br />
    end<br />
  end<br />
end</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2009/03/bypassing-mass-assignment-for-update_attributes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t overwrite Rails&#8217; built-in instance variables</title>
		<link>http://blog.lrdesign.com/2009/02/dont-overwrite-rails-built-in-instance-variables/</link>
		<comments>http://blog.lrdesign.com/2009/02/dont-overwrite-rails-built-in-instance-variables/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 02:40:36 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=46</guid>
		<description><![CDATA[So I'm hammering away at a project tonight, writing a few specifications for a module.  I've changed very little - or so I think - when five of my specifications start reporting this error: NoMethodError in 'LoansController POST 'create' with valid parameters should succeed' undefined method `env' for This happens on the line where I [...]]]></description>
			<content:encoded><![CDATA[<p>So I'm hammering away at a project tonight, writing a few specifications for a module.  I've changed very little - or so I think - when five of my specifications start reporting this error:</p>
<p><code>NoMethodError in 'LoansController POST 'create' with valid parameters should succeed'<br />
undefined method `env' for <LoanRequest:0x3729e00></code></p>
<p>This happens on the line where I call <code>post :create</code> in a controller spec.   Undefined method 'env'?   What's that about?  I'm certainly not trying to call a method named "env".</p>
<p>It took me a little bit to figure out what was going on.  See, this series of tests needed access to a particular LoanRequest object I was pulling out of fixtures.   So I'd put above the tests:</p>
<p><code>before(:each) do<br />
  ... some other stuff ...<br />
  @request = loan_requests(:johns_loan_request)  # fetch fixture<br />
end</code></p>
<p>Well, kids, it just so turns out that it's a bad idea to overwrite the <code>@request</code> instance variable in any rails context.   Who knew?</p>
<p>Come to think of it, it would be nice to change the accessibility and/or mutability of Rails' basic instance variables and classes to prevent this kind of accidental overwrite by the programmer.  Because when you make that mistake, it's invariably a bit of a pain to figure out because the error it causes is obscure.</p>
<p>Maybe I'll have to dig into the code one of these days to see if anything can be done about it. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2009/02/dont-overwrite-rails-built-in-instance-variables/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fixing problems with sphinx search</title>
		<link>http://blog.lrdesign.com/2008/07/fixing-problems-with-sphinx-search/</link>
		<comments>http://blog.lrdesign.com/2008/07/fixing-problems-with-sphinx-search/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 17:44:02 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[foxy fixtures]]></category>
		<category><![CDATA[Insoshi]]></category>
		<category><![CDATA[sphinx]]></category>
		<category><![CDATA[Ultrasphinx]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=42</guid>
		<description><![CDATA[I've been working a lot this week with sphinx and ultrasphinx on a project that's a fork of Insoshi.    Insoshi is in the process of switching search from ferret to sphinx, and sphinx has been integrated into the Insoshi edge branch. I've had dozens of problems, in fact it's fair to say I've spent upwards [...]]]></description>
			<content:encoded><![CDATA[<p>I've been working a lot this week with <a href="http://www.sphinxsearch.com/">sphinx</a> and <a href="http://agilewebdevelopment.com/plugins/ultrasphinx">ultrasphinx</a> on a project that's a fork of <a href="http://insoshi.com">Insoshi</a>.    Insoshi is in the process of switching search from ferret to sphinx, and sphinx has been integrated into the Insoshi edge branch.</p>
<p>I've had dozens of problems, in fact it's fair to say I've spent upwards of 15 hours just debugging ultrasphinx and getting my tests to pass.   There were several problems; here are the main three and how I fixed each one.</p>
<p>This should be useful to anyone upgrading Insoshi to the sphinx version, or to anyone else trying to get ultrasphinx working in their Rails project.   I definitely don't recommend starting with this post if you're just starting out with sphinx.  Instead, go read this much better <a href="http://blog.insoshi.com/2008/07/17/searching-a-ruby-on-rails-application-with-sphinx-and-ultrasphinx/">introductory tutorial</a> from the guys over at Insoshi.  Then if you have problems, come back here and you may find solutions.</p>
<h2>Getting search tests (or specs) to pass with sphinx</h2>
<p>This one is pretty simple, in retrospect, but it can be frustrating and opaque if you are used to ferret.  Unlike ferret, sphinx (at least via ultrasphinx) runs only via a daemon.   Where acts_as_ferret uses a daemon only for the production environment and just accesses the index files directly in test or development, ultrasphinx can only get to the indexes through the daemon.</p>
<p>So, to run your tests, you just build up the indexes for test and run them.  In this case, I'm running the specs for Insoshi's searches controller:</p>
<h4>From the command line in $RAILS_ROOT:</h4>
<p><code>rake db:test:prepare<br />
rake ultrasphinx:configure RAILS_ENV=test<br />
rake ultrasphinx:index RAILS_ENV=test<br />
rake ultrasphinx:daemon:start RAILS_ENV=test<br />
script/spec spec/controllers/searches_controller_spec.rb</code></p>
<p>The problem, of course, is that it doesn't work!   The reason is that db:test:prepare creates the <em>structure</em> of your database, but doesn't load any of your fixtures as data: the test db is empty..  So when you run the index command, an empty index is built.   You can see this from the output of that first index command, which will look something like this:</p>
<p><code>collected 0 docs, 0.0 MB<br />
total 0 docs, 0 bytes<br />
total 0.078 sec, 0.00 bytes/sec, 0.00 docs/sec</code></p>
<p>Ultrasphinx has built an empty index.</p>
<h3>The solution</h3>
<p>The solution, believe it or not, is to run the tests, let them fail, re-index, and run the tests again (Many thanks to Long Nguyen at Insoshi for helping me figure this one out):</p>
<p><code>rake db:test:prepare<br />
rake ultrasphinx:configure RAILS_ENV=test<br />
rake ultrasphinx:index RAILS_ENV=test<br />
rake ultrasphinx:daemon:start RAILS_ENV=test<br />
script/spec spec/controllers/searches_controller_spec.rb   #FAIL!!<br />
rake ultrasphinx:index RAILS_ENV=test<br />
script/spec spec/controllers/searches_controller_spec.rb   #PASS!!<br />
</code></p>
<p>The first attempt to run the specs loads the fixtures, and leaves them in the database, thus letting the subsequent index command build an actual index.</p>
<h2>Running sphinx for both test and development environments at the same time</h2>
<p>The next big challenge was enabling behavior-driven development.  I like to work with autotest and growl running constantly in the background.   But this was tough to do with sphinx, because the daemon needed to be stopped and re-started, and the index re-created for each environment, alternately running all of the above commands either with or without RAILS_ENV=test.  </p>
<p>The solution is to set up your ultrasphinx base configuration to completely separate both the test and development indexes and to let the daemons for the two environments listen on different ports.  I had tried something like this and come close, but not quite, when Long at Insoshi again bailed me out.   You need to change the port (in two places), and the paths of the logs, pidfile, and index directories so that test and development daemons are using entirely separate resources.   Here's a diff of my test.conf and default.conf:</p>
<p><code>33c33<br />
<   port = 3312<br />
---<br />
>   port = 3322<br />
35c35<br />
<   log = log/searchd.log<br />
---<br />
>   log = log/searchd_test.log<br />
39c39<br />
<   pid_file = log/searchd.pid<br />
---<br />
>   pid_file = log/searchd_test.pid<br />
50c50<br />
<   server_port = 3312<br />
---<br />
>   server_port = 3322<br />
57c57<br />
<   sql_range_step = 5000<br />
---<br />
>   sql_range_step = 999999999<br />
64c64<br />
<   path = sphinx<br />
---<br />
>   path = sphinx_test</code></p>
<p>The <code>sql_range_step</code> is related to the next issue, which is that sphinx does not play well with foxy fixtures.   Anyway, make the above changes and you should be able to run test and development sphinx daemons at the same time:</p>
<p><code>rake db:test:prepare<br />
rake ultrasphinx:configure<br />
rake ultrasphinx:configure RAILS_ENV=test<br />
rake ultrasphinx:index<br />
rake ultrasphinx:index RAILS_ENV=test<br />
rake ultrasphinx:daemon:start<br />
rake ultrasphinx:daemon:start RAILS_ENV=test<br />
</code></p>
<p>If it worked, you should see separate indexes in $RAILS_ROOT/sphinx and $RAILS_ROOT/sphinx_test, and two daemons running, which you can confirm with <code>ps waux | grep searchd</code>:<br />
<code>evan      1339   0.0  0.0    78100    292 s000  S     5:37PM   0:00.52 searchd --config <YOUR_RAILS_ROOT>/config/ultrasphinx/test.conf<br />
evan      1326   0.0  0.0    78100    292 s000  S     5:36PM   0:00.68 searchd --config <YOUR_RAILS_ROOT>/config/ultrasphinx/development.conf</code></p>
<h2>Getting sphinx to play well with foxy fixtures</h2>
<p>The next problem I discovered was that on some machines, but not others, running my search specs would result in these weird errors:<br />
<code>1)<br />
ActiveRecord::RecordNotFound in 'SearchesController Person searches should search by name'<br />
Couldn't find Person with ID=328556765<br />
/var/www/domains/unithrive/vendor/plugins/ultrasphinx/lib/ultrasphinx/search/internals.rb:308:in `reify_results'<br />
/var/www/domains/unithrive/vendor/plugins/ultrasphinx/lib/ultrasphinx/search/internals.rb:286:in `each'<br />
/var/www/domains/unithrive/vendor/plugins/ultrasphinx/lib/ultrasphinx/search/internals.rb:286:in `reify_results'<br />
/var/www/domains/unithrive/vendor/plugins/ultrasphinx/lib/ultrasphinx/search.rb:362:in `run'<br />
/var/www/domains/unithrive/vendor/plugins/ultrasphinx/lib/ultrasphinx/search/internals.rb:352:in `perform_action_with_retries'<br />
/var/www/domains/unithrive/vendor/plugins/ultrasphinx/lib/ultrasphinx/search.rb:342:in `run'<br />
/var/www/domains/unithrive/app/controllers/searches_controller.rb:38:in `index'<br />
./spec/controllers/searches_controller_spec.rb:51:<br />
script/spec:4:</code></p>
<p>When I poked into this "Couldn't find Person with ID=328556765" error, it seemed like sphinx was <em>almost</em> working.  The index was set up, and the search was finding someone in the index during the test.  Ultrasphinx was passing back the id 328556765, which didn't exist in the database.  So why would Sphinx "find" a record in its index but then pass back an ID for a database record that didn't exist?</p>
<p>And furthermore, why would it work on one machine, but not on another?</p>
<p>The brainstorm came when I checked what the actual database IDs were for this particular record, with Person.find_by_name("fixtures' name").id.  On machines where it worked, the id was a huge number (is it generally is with foxy fixtures), but on machines where it didn't work, the id was an <em>even huger</em> number. </p>
<p>Sphinx tries to make sure that all items that get indexed have a different index in sphinx, and it does this by multiplying all of your id's by N, where N is the number of models getting indexed, and adding an offset of 0 for the first model, 1 for the second, etc.   This guarantees that every record from every table will have a unique id.  In the case of this application, all of my Person records were getting indexed by sphinx as (Person#id * 4 + 2).   </p>
<h3>Danger, Will Robinson:  32-bit int rollover!</h3>
<p>The problem is that foxy fixtures generate their own ids from a hash of the fixture label, and those ids can be anywhere in the 32-bit unsigned integer space.  But Sphinx also stores ids as 32-bit unsigned integers.   This means if you happen to get a large fixture id, and then sphinx multiplies it by 4 (or whatever; it could be higher if you have more indexed models), your id will rollover and come out as (id * N + n) % (2^32).   Sphinx will store that result, and then when it finds the record in a search, it will try to recreate the original id by subtracting n and dividing by N ... giving you the wrong id.  Your test will fail to find the record.</p>
<p>Incidentally, this problem with foxy fixtures is why your test.base file needs the line <code>sql_range_step = 999999999</code>.  Sphinx builds indexes by searching a few ids at a time.  But the ids generated by foxy fixtures are so big that if sphinx only collects them in ranges of 5000 at a time, it will take forever to find them all.</p>
<p>After some googling, I found that these issues are discussed in a <a href="http://rubyforge.org/forum/message.php?msg_id=43937">thread over at RubyForge</a>. </p>
<h3>The solution</h3>
<p>I'm working on a plugin that monkeypatches foxy fixtures to create sequential, low-numbered IDs.  In the meantime, you can just compile sphinx to support 64-bit ids, which should give you plenty of headroom to handle foxy fixture ids multiplied by N in sphinx<sup>*</sup>:</p>
<h4>In your sphinx source directory:</h4>
<p><code>configure --enable-id64<br />
make<br />
sudo make install</code></p>
<p>That should do it.  Let me know in comments if any of this information helped you.</p>
<p><sup>*</sup>At least until you start approaching 2^32 models in your application, that is.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2008/07/fixing-problems-with-sphinx-search/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rails 2.1 gotcha: don&#8217;t name an ActiveRecord field &#8216;changes&#8217; !</title>
		<link>http://blog.lrdesign.com/2008/07/rails-21-gotcha-dont-name-an-activerecord-field-changes/</link>
		<comments>http://blog.lrdesign.com/2008/07/rails-21-gotcha-dont-name-an-activerecord-field-changes/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 00:00:06 +0000</pubDate>
		<dc:creator>Evan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[changes]]></category>
		<category><![CDATA[dirty]]></category>
		<category><![CDATA[field names]]></category>

		<guid isPermaLink="false">http://blog.lrdesign.com/?p=37</guid>
		<description><![CDATA[In one of my Rails projects, I maintain a user-visible log of updates to the database by recording entries into a table that looks like this (from schema.rb): create_table "log_entries", :force => true do &#124;t&#124; t.integer "user_id", :limit => 11 t.datetime "created_at" t.datetime "updated_at" t.string "item_type" t.integer "source_id", :limit => 11 t.string "table" t.string "action" [...]]]></description>
			<content:encoded><![CDATA[<p>In one of my Rails projects, I maintain a user-visible log of updates to the database by recording entries into a table that looks like this (from schema.rb):</p>
<p><code>create_table "log_entries", :force => true do |t|<br />
    t.integer  "user_id",    :limit => 11<br />
    t.datetime "created_at"<br />
    t.datetime "updated_at"<br />
    t.string   "item_type"<br />
    t.integer  "source_id",  :limit => 11<br />
    t.string   "table"<br />
    t.string   "action"<br />
    t.text     "changes"<br />
  end</code></p>
<p>Whenever a record is created, updated, or deleted, I create and save an instance of <code>LogEntry</code>, containing for example <code>{:table => 'task', :action => 'update'}</code> and in the 'changes' column I save a serialized hash showing which attributes of the task object changed before and after save.  In addition, I save which logged-in user made these changes, and when.</p>
<p>This is convenient, it gives my client a log that's much more user-accessible and allows them to easily back-trace who did what to the database and when, which is important for their process and certain certifications.</p>
<p>When I upgraded the project to Rails 2.1 a couple of weeks ago, most of the code still worked fine, but the hashes showing the object changes were no longer showing up in views of the log.  The culprit turned out to be Rails 2.1's new dirty feature.   Why?  Because it adds the method 'changes' to ActiveRecord::Base.   This is a great new feature that lets you know what has changed to an ActiveRecord object since you loaded it from the database, with all kinds of benefits like doing more selective updates, or not writing to the database at all if no changes have occurred, thus reducing system load if you call <code>save!</code> a lot.</p>
<p>Unfortunately, the new method 'changes' was obscuring my attribute 'changes' in some circumstances, and at the very least confusing the heck out of me, the programmer.</p>
<p>The solution, of course, is not to name your fields anything that corresponds to any Ruby core method or any method of ActiveRecord::Base.   I fixed my problem with a migration to rename the column 'details':</p>
<p><code>def self.up<br />
	rename_column  :log_entries, :changes, :details<br />
end</p>
<p>def self.down<br />
	rename_column  :log_entries, :details, :changes<br />
end	</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lrdesign.com/2008/07/rails-21-gotcha-dont-name-an-activerecord-field-changes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
