<?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>SmartLogic Solutions Blog &#187; ActiveRecord</title>
	<atom:link href="http://blog.smartlogicsolutions.com/category/activerecord/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.smartlogicsolutions.com</link>
	<description>News and updates from the people at SmartLogic Solutions</description>
	<lastBuildDate>Tue, 30 Nov 2010 21:39:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Rails 2.3 Nested Object Forms: I&#8217;m not Crazy about Them</title>
		<link>http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 15:00:51 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[ActionPack]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[accepts_nested_attributes_for]]></category>
		<category><![CDATA[nested object forms]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails2.3]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=529</guid>
		<description><![CDATA[I&#8217;m a couple of weeks late, but I just finished reviewing Rails 2.3 Nested Object Forms. While a very nice and &#8220;magical&#8221; feature, I&#8217;ve got to admit that I&#8217;m really not that crazy about how it works. Let me be the first to admit that there&#8217;s no one right way to do things. In fact, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a couple of weeks late, but I just finished reviewing <a href="http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes">Rails 2.3 Nested Object Forms</a>.  While a very nice and &#8220;magical&#8221; feature, I&#8217;ve got to admit that I&#8217;m really not that crazy about how it works.</p>
<p>Let me be the first to admit that there&#8217;s no one right way to do things.  In fact, I&#8217;m writing this post particularly because I have a few objections to how this functionality is ultimately exposed, and I&#8217;d like to hear arguments from those who disagree.  In other words, let me acknowledge the possibility that I am the misguided one.</p>
<p><span id="more-529"></span></p>
<h3>Review of Nested Object Forms</h3>
<p>As a quick review, we can now prepare our models for nested object mass assignment:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:name</span>
&nbsp;
  has_many <span style="color:#ff3333; font-weight:bold;">:children</span>
  accepts_nested_attributes_for <span style="color:#ff3333; font-weight:bold;">:children</span>
    <span style="color:#008000; font-style:italic;"># can also be used on has_one etc.. associations</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Child <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  belongs_to <span style="color:#ff3333; font-weight:bold;">:person</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>We specify which nested relationships can be passed in via mass assignment using the <code>accepts_nested_attributes_for()</code> function.  Continuing the example, we can now execute the following to actually save a person and two children at the same time:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">person = Person.<span style="color:#9900CC;">create</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'George'</span>, <span style="color:#ff3333; font-weight:bold;">:children_attributes</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;new_1&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:name <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Amy'</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#996600;">&quot;new_2&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:name <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Stephanie'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>For full disclosure, my console session from start to finish:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">john-mbp:playground john$ rails <span style="color: #660033;">-v</span>
Rails 2.3.0
john-mbp:playground john$ rails anewapp
...
...
john-mbp:playground john$ <span style="color: #7a0874; font-weight: bold;">cd</span> anewapp<span style="color: #000000; font-weight: bold;">/</span>
john-mbp:anewapp john$ ruby script<span style="color: #000000; font-weight: bold;">/</span>generate model person name:string
...
john-mbp:anewapp john$ ruby script<span style="color: #000000; font-weight: bold;">/</span>generate model child name:string person_id:integer
...
&nbsp;
<span style="color: #666666; font-style: italic;"># edit app/models/person.rb as above</span>
<span style="color: #666666; font-style: italic;"># edit app/models.child.rb as above</span>
&nbsp;
john-mbp:anewapp john$ rake db:migrate
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>john<span style="color: #000000; font-weight: bold;">/</span>playground<span style="color: #000000; font-weight: bold;">/</span>anewapp<span style="color: #7a0874; font-weight: bold;">&#41;</span>
==  CreatePeople: migrating ===================================================
<span style="color: #660033;">--</span> create_table<span style="color: #7a0874; font-weight: bold;">&#40;</span>:people<span style="color: #7a0874; font-weight: bold;">&#41;</span>
   -<span style="color: #000000; font-weight: bold;">&gt;</span> 0.0044s
==  CreatePeople: migrated <span style="color: #7a0874; font-weight: bold;">&#40;</span>0.0046s<span style="color: #7a0874; font-weight: bold;">&#41;</span> ==========================================
&nbsp;
==  CreateChildren: migrating =================================================
<span style="color: #660033;">--</span> create_table<span style="color: #7a0874; font-weight: bold;">&#40;</span>:children<span style="color: #7a0874; font-weight: bold;">&#41;</span>
   -<span style="color: #000000; font-weight: bold;">&gt;</span> 0.0041s
==  CreateChildren: migrated <span style="color: #7a0874; font-weight: bold;">&#40;</span>0.0045s<span style="color: #7a0874; font-weight: bold;">&#41;</span> ========================================
&nbsp;
john-mbp:anewapp john$ ruby script<span style="color: #000000; font-weight: bold;">/</span>console 
Loading development environment <span style="color: #7a0874; font-weight: bold;">&#40;</span>Rails 2.3.0<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&gt;&gt;</span> person = Person.create<span style="color: #000000; font-weight: bold;">!</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>:name =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'George'</span>, :children_attributes =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;new_1&quot;</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>:name =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'Amy'</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>, <span style="color: #ff0000;">&quot;new_2&quot;</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>:name =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'Stephanie'</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #666666; font-style: italic;">#&lt;Person id: 1, name: &quot;George&quot;, created_at: &quot;2009-02-24 00:49:21&quot;, updated_at: &quot;2009-02-24 00:49:21&quot;&gt;</span>
<span style="color: #000000; font-weight: bold;">&gt;&gt;</span> person.children
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #666666; font-style: italic;">#&lt;Child id: 1, name: &quot;Amy&quot;, person_id: 1, created_at: &quot;2009-02-24 00:49:21&quot;, updated_at: &quot;2009-02-24 00:49:21&quot;&gt;, #&lt;Child id: 2, name: &quot;Stephanie&quot;, person_id: 1, created_at: &quot;2009-02-24 00:49:21&quot;, updated_at: &quot;2009-02-24 00:49:21&quot;&gt;]</span>
<span style="color: #000000; font-weight: bold;">&gt;&gt;</span> person.children.size
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">2</span></pre></div></div>

<p>Pretty cool, huh?  I agree.  I think this is fantastic, and with the integration with fields_for, it will really ease a lot of the pain that previously existed with multi-model forms.</p>
<p>This said, I&#8217;ve got a few major bones to pick with how it&#8217;s implemented.</p>
<h3>So What&#8217;s Wrong?</h3>
<p>The primary issue is the fact that this functionality is statically defined (in that you can&#8217;t turn it on/off in specific scenarios).  Why is this an issue?  Well, this is a potentially dangerous functionality to expose everywhere.  Let&#8217;s say that you wanted to take advantage of this new feature to allow administrators to create new accounts that came pre-loaded with a complementary $X credit to their accounts.  So you built a form for admins to fill out that included a <code>fields_for :credits</code> to achieve this single-form implementation of an account with credits.  Now, in order to avail of this, I need to turn on the nested mass assignment.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_many <span style="color:#ff3333; font-weight:bold;">:credits</span>
  accepts_nested_attributes_for <span style="color:#ff3333; font-weight:bold;">:credits</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Credit <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  belongs_to <span style="color:#ff3333; font-weight:bold;">:person</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Wait&#8230;.I&#8217;ve just turned this feature on globally&#8230;..I can&#8217;t just make it available at the controller level?  But isn&#8217;t the controller where I define authorization, who can edit/update/create what?  Precisely.  </p>
<p>So&#8230;.unless I want to go old school and rewrite this all by hand, anytime I want to render a person form (e.g. on an &#8220;Edit My Profile&#8221; link for authenticated users), I need to recall that I&#8217;ve exposed myself to a possible POST data hack (anyone who understands this feature in rails will know how to handcraft the POST data).  This is a fairly ridiculous thing to expect on a project of any nontrivial size.</p>
<p>However, there&#8217;s another way around this issue.  Rather than rewriting all of the multi-model form stuff by hand, I could simply ward off the extra parameters at the controller level, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ProfileController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  before_filter <span style="color:#ff3333; font-weight:bold;">:remove_nested_params</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> update
    <span style="color:#0066ff; font-weight:bold;">@user</span> = User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>current_user.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@user</span>.<span style="color:#9900CC;">update_attributes</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    redirect_to profile_path
  <span style="color:#9966CC; font-weight:bold;">rescue</span>
    render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'edit'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  protected
    <span style="color:#9966CC; font-weight:bold;">def</span> remove_nested_params
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:credits</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This works fine in isolation or for a one-off, but again, this is a piece of information that is going to be lost as the project trudges along.  Your team will forget this, and someone is going to forget to &#8220;close the hole&#8221; when adding that new &#8220;quick edit profile&#8221; form that only shows their email address and display name.</p>
<h3>Counter Suggestions</h3>
<p>I would advocate any solution where this behavior was pushed out to controllers.  That said, I don&#8217;t have an airtight procedure planned out.  I will, however, leave you with a few suggestions.</p>
<p>We could implement it around_filter style where the feature is enabled/disabled in an around_filter.  The primary benefit of this approach would be that the majority of the code could probably stay put in ActiveRecord.  We&#8217;d just need to expose hooks to turn it on/off.  Then we could define a controller-level meta-function (e.g. filter_parameter_logging) that could set which actions to apply the behavior on, or which models can be nested.  The syntax could look like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ProfileController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  allow_nested_assignment_for User, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:children</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:update</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I&#8217;ll be perfectly honest in that I don&#8217;t love this suggestion.  It incorrectly scopes this authorization tweak to the whole action and any before/after filters that execute in between it (still leaving holes, albeit smaller) as opposed to scoping it directly to the single save! action that we really want to special-case.  If we perhaps exposed a separate save_with_nested() function, then we could isolate the scope down to the specific call.  Needless to say, I doubt this is a course of action rails would take, and it&#8217;s not one I would advocate.</p>
<p>Another alternative would be to keep the functionality as is, but then allow you to override or extend it at the controller level (a la my initial suggestion).  This would allow developers to avail of the benefits in the less-risky areas, and then conditionally avail of them in more risky areas by simply turning it on for specific controller/action combos.  In this case, we&#8217;d define a basic harmless nested assignment baseline in the model, and the more risky nested assignment in those controllers where we wanted to isolate it, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_many <span style="color:#ff3333; font-weight:bold;">:children</span>
  has_many <span style="color:#ff3333; font-weight:bold;">:credits</span>
  accepts_nested_attributes_for <span style="color:#ff3333; font-weight:bold;">:children</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#6666ff; font-weight:bold;">Admin::PeopleController</span> <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  allow_nested_assignment_for User, <span style="color:#ff3333; font-weight:bold;">:credits</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:update</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The primary benefit of an approach like this is that it aligns properly to a developer&#8217;s train of thought.  When you go to add a trivial feature, you don&#8217;t think &#8220;I need to close that gap my unrelated nontrivial feature added for me.&#8221;  However, when you go to add a nontrival feature (like allowing an admin to auto-create credits in their new account form), you do think &#8220;what do I need to differently?&#8221;  In the former case, the developer thinks his new feature is trivial, and doesn&#8217;t expect to have do anything exceptional for it.  In the latter case, the developer thinks his new feature is nontrivial, and will think about it from a &#8220;what extra work does that mean for me?&#8221; standpoint.</p>
<h3>Closing Thoughts</h3>
<p>One of the biggest things that worries me is that no one is talking about this.  The whole community <a href="http://rails.uservoice.com/pages/rails3">requested this feature</a>, and at this point it has received quite a bit of fanfare.  But there are some clear ways to accidentally screw yourself that just aren&#8217;t being mentioned as caveats.</p>
<p>To be entirely blunt, I just feel like this is plugin material at this point.  Though I commend rails for opening up its feature set to a community vote, I fear that we may have misstepped with this feature in particular.  I&#8217;m very curious to hear what others think.  (Be gentle with the flame)</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/" rel="bookmark" class="crp_title">Using ActiveRecord&#8217;s to_xml to produce custom xml including deep level associations</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/04/25/reintroducing-sanitize_email-work-with-production-email-without-fear/" rel="bookmark" class="crp_title">Reintroducing sanitize_email | Work with Production Email without Fear</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/23/dont-abuse-the-session/" rel="bookmark" class="crp_title">Don&#8217;t Abuse the Session</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/" rel="bookmark" class="crp_title">Timecop: Freeze Time in Ruby for Better Testing</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/05/mapresources-and-custom-nested-routes/" rel="bookmark" class="crp_title">map.resources and custom nested routes</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Making WillPaginate and Rails to_xml play nice with ActiveResource</title>
		<link>http://blog.smartlogicsolutions.com/2008/10/10/making-willpaginate-and-rails-to_xml-play-nice-with-activeresource/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/10/10/making-willpaginate-and-rails-to_xml-play-nice-with-activeresource/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 19:48:57 +0000</pubDate>
		<dc:creator>Scott Davis</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Scott Davis]]></category>
		<category><![CDATA[Serialization]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[Rails Will_Paginate to_xml ActiveResource]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=305</guid>
		<description><![CDATA[We are currently working on a project that involves Flex and active resource + will_paginate and we needed to be able to paginate the xml transactions easily. Unfortunately, will_paginate and to_xml don&#8217;t play nicely when it comes to adding the current_page, total_pages, and page attributes to the xml. After many failed attempts I went looking around github [...]]]></description>
			<content:encoded><![CDATA[<p>We are currently working on a project that involves Flex and active resource + will_paginate and we needed to be able to paginate the xml transactions easily. Unfortunately, will_paginate and to_xml don&#8217;t play nicely when it comes to adding the current_page, total_pages, and page attributes to the xml. After many failed attempts I went looking around <a href="http://github.com">github</a> and found in a few <a href="http://github.com/agile/will_paginate/tree/master">forks</a> of <a href="http://github.com/mislav/will_paginate/tree/master/">will paginate</a> that some people had solved this problem but, I didn&#8217;t want to install another version of the gem to risk breaking other apps on the server so I did it the rails way!</p>
<p>I started by creating a module that opens up the will_paginate <a href="http://github.com/mislav/will_paginate/tree/master/lib/will_paginate/collection.rb">collection</a> class and includes ActiveResource and alias method chain the to_xml method to include these values. Example code below.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#enviroment.rb</span>
...
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'to_xml_extensions'</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#lib/to_xml_extensions.rb</span>
<span style="color:#9966CC; font-weight:bold;">module</span> WillPaginateHelpers
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">ActiveSupport::CoreExtensions</span>::<span style="color:#CC0066; font-weight:bold;">Array</span>::Conversions
  <span style="color:#9966CC; font-weight:bold;">def</span> to_xml_with_collection_type<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>
        serializeable_collection.<span style="color:#9900CC;">to_xml_without_collection_type</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;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
          xml.<span style="color:#9900CC;">tag</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:current_page</span>, <span style="color:#006600; font-weight:bold;">&#123;</span>:type <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveSupport::CoreExtensions</span>::<span style="color:#CC00FF; font-weight:bold;">Hash</span>::<span style="color:#6666ff; font-weight:bold;">Conversions::XML_TYPE_NAMES</span><span style="color:#006600; font-weight:bold;">&#91;</span>current_page.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, current_page<span style="color:#006600; font-weight:bold;">&#41;</span>
          xml.<span style="color:#9900CC;">tag</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:per_page</span>, <span style="color:#006600; font-weight:bold;">&#123;</span>:type <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveSupport::CoreExtensions</span>::<span style="color:#CC00FF; font-weight:bold;">Hash</span>::<span style="color:#6666ff; font-weight:bold;">Conversions::XML_TYPE_NAMES</span><span style="color:#006600; font-weight:bold;">&#91;</span>per_page.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, per_page<span style="color:#006600; font-weight:bold;">&#41;</span>
          xml.<span style="color:#9900CC;">tag</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:total_entries</span>, <span style="color:#006600; font-weight:bold;">&#123;</span>:type <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveSupport::CoreExtensions</span>::<span style="color:#CC00FF; font-weight:bold;">Hash</span>::<span style="color:#6666ff; font-weight:bold;">Conversions::XML_TYPE_NAMES</span><span style="color:#006600; font-weight:bold;">&#91;</span>total_entries.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, total_entries<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>.<span style="color:#CC0066; font-weight:bold;">sub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>type=<span style="color:#996600;">&quot;array&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>type=<span style="color:#996600;">&quot;collection&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      alias_method_chain <span style="color:#ff3333; font-weight:bold;">:to_xml</span>, <span style="color:#ff3333; font-weight:bold;">:collection_type</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">def</span> serializeable_collection <span style="color:#008000; font-style:italic;">#:nodoc:</span>
        <span style="color:#008000; font-style:italic;"># Ugly hack because to_xml will not yield the XML Builder object when empty?</span>
        empty? ? returning<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">clone</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span> c.<span style="color:#9900CC;">instance_eval</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>i<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#9966CC; font-weight:bold;">def</span> empty?; <span style="color:#0000FF; font-weight:bold;">false</span>; <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span> : <span style="color:#0000FF; font-weight:bold;">self</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">WillPaginate::Collection</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span>:<span style="color:#9966CC; font-weight:bold;">include</span>, WillPaginateHelpers<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>This now gives me the proper xml when I call to_xml</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;time-cards</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;collection&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;current_page</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;integer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/current_page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;per_page</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;integer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>25<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/per_page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;total_entries</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;integer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>108<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/total_entries<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;time_card<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;approved</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;boolean&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/approved<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;billable</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;boolean&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/billable<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;created_at</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;datetime&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>2008-10-10T14:04:13-04:00<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/created_at<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;date</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;datetime&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>2008-10-10T14:04:13-04:00<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/date<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;has_been_billed</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;boolean&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/has_been_billed<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;has_been_paid</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;boolean&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>true<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/has_been_paid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hours</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;float&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>2.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hours<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;integer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>98<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;is_overtime</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;boolean&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/is_overtime<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;task_id</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;integer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>6<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/task_id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;updated_at</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;datetime&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>2008-10-10T14:04:13-04:00<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/updated_at<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;user_id</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;integer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/user_id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/time_card<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  ...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/timecards<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/10/28/faking-a-will-paginate-collection-on-an-active-resource-model/" rel="bookmark" class="crp_title">Faking a Will Paginate Collection on an Active Resource model</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/13/ruby-on-rails-polymorphic-association-benchmarks/" rel="bookmark" class="crp_title">Ruby on Rails Polymorphic Association Benchmarks</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/01/microsoft-webdav-opens-document-as-read-only-when-using-railsdav/" rel="bookmark" class="crp_title">Microsoft WebDav opens document as Read-Only when using RailsDav</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/" rel="bookmark" class="crp_title">Using ActiveRecord&#8217;s to_xml to produce custom xml including deep level associations</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/03/error-in-will_paginate-gem-running-rails-210/" rel="bookmark" class="crp_title">Error in will_paginate gem running Rails 2.1.0</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/10/10/making-willpaginate-and-rails-to_xml-play-nice-with-activeresource/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Fork Pools in Ruby on Rails</title>
		<link>http://blog.smartlogicsolutions.com/2008/09/19/fork-pools-in-ruby-on-rails/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/09/19/fork-pools-in-ruby-on-rails/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 13:49:07 +0000</pubDate>
		<dc:creator>Nick Gauthier</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Nick Gauthier]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=262</guid>
		<description><![CDATA[If you need to process 1000 items independently, the simplest thing to do is to handle them one-by-one. But what if there is a large delay that is not caused by your application when you handle an item? What if you need to make a 100ms web request per item, only to do about 10ms [...]]]></description>
			<content:encoded><![CDATA[<p>If you need to process 1000 items independently, the simplest thing to do is to handle them one-by-one. But what if there is a large delay that is not caused by your application when you handle an item? What if you need to make a 100ms web request per item, only to do about 10ms of processing on that item? This would take 1000 x 110ms (100ms to wait, 10ms to process)!</p>
<p>So what do we do?</p>
<p><span id="more-262"></span></p>
<p>You could multithread the application, and the simple way is to say:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">items.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>i<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>i<span style="color:#006600; font-weight:bold;">|</span>
    handle<span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The problem is that this will spawn 1000 threads, each of which will go out simultaneously, and after 100ms when they come back your system will be overloaded.</p>
<p>Ideally, we would like to <a href="http://en.wikipedia.org/wiki/Pipelining">pipeline</a> the processing to that each ms of execution we are working on one thread, so our cpu is used to the max as well as our internet connection. In this ideal situation, the task would take 10000ms (10ms per item) + 100ms (time to wait for first to come back).</p>
<p>So a little calculation lets us know that we want 10 threads working at once, each 10ms apart from each other. Now we&#8217;re going to get into thread pooling! Actually, I am going to be working with forking, which is more memory intensive but it can actually use multiple cores, so it&#8217;s more useful. Using enterprise ruby, a lot of that memory is shared, so it&#8217;s not so bad.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># here we keep our items</span>
items_to_process = my_items
<span style="color:#008000; font-style:italic;"># max at once</span>
max_process = <span style="color:#006666;">10</span>
<span style="color:#008000; font-style:italic;"># keep track of the processes running</span>
processing_pids = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#008000; font-style:italic;"># while we have items to work on and we aren't done with the</span>
<span style="color:#008000; font-style:italic;"># ones we're working on</span>
<span style="color:#9966CC; font-weight:bold;">while</span> !items_to_process.<span style="color:#9900CC;">empty</span>? <span style="color:#9966CC; font-weight:bold;">or</span> !processing_pids.<span style="color:#9900CC;">empty</span>? <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#008000; font-style:italic;"># If we are below our max number of running items,</span>
  <span style="color:#008000; font-style:italic;"># add a thread</span>
  <span style="color:#9966CC; font-weight:bold;">while</span> items_to_process.<span style="color:#9900CC;">size</span> <span style="color:#006600; font-weight:bold;">&lt;</span> max_process <span style="color:#9966CC; font-weight:bold;">do</span>
    item_to_process = items_to_process.<span style="color:#9900CC;">pop</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># keep the connection across the forks</span>
    <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">remove_connection</span>
    pid_starting = <span style="color:#CC00FF; font-weight:bold;">Process</span>.<span style="color:#CC0066; font-weight:bold;">fork</span><span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">establish_connection</span>
      process_item<span style="color:#006600; font-weight:bold;">&#40;</span>item_to_process<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">remove_connection</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">establish_connection</span>
    <span style="color:#008000; font-style:italic;"># keep track of the item by pid.</span>
    <span style="color:#008000; font-style:italic;">#You could put other stuff in this hash too</span>
    processing_pids<span style="color:#006600; font-weight:bold;">&#91;</span>pid_starting<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#123;</span>:item <span style="color:#006600; font-weight:bold;">=&gt;</span> item_to_process<span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># pick up a finished task. This will get one task whose</span>
  <span style="color:#008000; font-style:italic;"># parent is the current thread.</span>
  <span style="color:#008000; font-style:italic;"># If it doesn't get one immediately, it returns nil and loops</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> pid_done = <span style="color:#CC00FF; font-weight:bold;">Process</span>.<span style="color:#9900CC;">wait</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0</span>, <span style="color:#CC00FF; font-weight:bold;">Process</span>::WNOHANG<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># grab it out of the hash</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> job_finished = processing_pids.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span>pid_done<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;We finished item #{job_finished[:item].to_s}&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#008000; font-style:italic;"># quick nap so we don't hit this loop a lot</span>
  <span style="color:#CC0066; font-weight:bold;">sleep</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0.001</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The basic idea here is to keep a pool of forks running, and each 1ms we&#8217;ll check to see if any finished and need to be started. When a fork finishes we can do any post-processing, and the next time around the loop a new one will be added.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/06/11/multithreading-in-ruby-on-rails/" rel="bookmark" class="crp_title">Multithreading in Ruby on Rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2007/06/06/eclipse-32-and-out-of-memory-errors/" rel="bookmark" class="crp_title">Eclipse 3.2 and &#8220;Out Of Memory&#8221; errors</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/" rel="bookmark" class="crp_title">Using ActiveRecord&#8217;s to_xml to produce custom xml including deep level associations</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/07/subversion-timestamps-capistrano-finalize_update/" rel="bookmark" class="crp_title">Subversion Timestamps + Capistrano finalize_update</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/11/losing-data-drag-and-drop-custom-class-flex-serialization/" rel="bookmark" class="crp_title">Losing Data When Drag and Dropping Custom Classes in Flex?</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/09/19/fork-pools-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using ActiveRecord&#8217;s to_xml to produce custom xml including deep level associations</title>
		<link>http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 18:49:34 +0000</pubDate>
		<dc:creator>Glenn Gentzke</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Glenn Gentzke]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[deep level associations]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[to_xml]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=237</guid>
		<description><![CDATA[ActiveRecord provides a powerful method to all its records called to_xml. Most web developers using RoR should be familiar with its usage and hopefully use it for their simple xml production needs. But what do you do when you need to produce xml that is selective, includes associations, or contains custom tags? There are many [...]]]></description>
			<content:encoded><![CDATA[<p>ActiveRecord provides a powerful method to all its records called <strong>to_xml</strong>.  Most web developers using RoR should be familiar with its usage and hopefully use it for their simple xml production needs.  But what do you do when you need to produce xml that is selective, includes associations, or contains custom tags?  There are many ways to manipulate to_xml&#8217;s output and I&#8217;ll explain a few below.<br />
<span id="more-237"></span></p>
<h3>The Options Hash</h3>
<p>The most obvious way to change the output is to use the options hash <a href="http://api.rubyonrails.org/classes/ActiveRecord/XmlSerialization.html">outlined in the docs</a>.  A short list of options you might want to explore is:</p>
<ul>
<li>except => [:attr1, :attr2] &#8212; excludes attributes in array from output</li>
<li>only => [:attr1, :attr2] &#8212; output contains only the specified attributes</li>
<li>include	 => [:assoc1, :assoc2] &#8212; calls to_xml on the given first level association and nests it in the output</li>
<li>methods => [:meth1, :meth2] &#8212; adds a tag to output in the format <em>&lt;method-name&gt;[method output]&lt;/method-name&gt;</em></li>
</ul>
<p>Usage is incredibly simple:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#008000; font-style:italic;"># grab xml for a record and its child</span>
  my_record.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span>:<span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:child</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># same, but only output the ids and names (assuming both have these attributes)</span>
  my_record.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#93;</span>, :<span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:child</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<h3>Behold, the Builder</h3>
<p>A fantastic feature of to_xml that <a href="http://ryandaigle.com/articles/2007/4/13/what-s-new-in-edge-rails-a-more-flexible-to_xml">Ryan blogged about last year</a> is that it yields the builder, thus allowing you to add arbitrary tags into the output.  What&#8217;s more is you can pass the builder into another object&#8217;s to_xml method inside the outer block and produced nested xml.</p>
<p>For example:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#008000; font-style:italic;"># Arbitrarily insert a tag</span>
  my_record.<span style="color:#9900CC;">to_xml</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
    xml.<span style="color:#9900CC;">some_tag</span> some_value   <span style="color:#008000; font-style:italic;">#=&gt; &lt;some_tag&gt;some_value&lt;/some_tag&gt;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># I want to get xml for my record and all its children</span>
  my_record.<span style="color:#9900CC;">to_xml</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
    my_record.<span style="color:#9900CC;">children</span>.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>child<span style="color:#006600; font-weight:bold;">|</span> child.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>You can nest as deep as you want without overriding a model&#8217;s own to_xml method:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  output = my_record.<span style="color:#9900CC;">to_xml</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
    my_record.<span style="color:#9900CC;">children</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>child<span style="color:#006600; font-weight:bold;">|</span>
      child.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>fxml<span style="color:#006600; font-weight:bold;">|</span>
        child.<span style="color:#9900CC;">grandchild</span>.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> fxml, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</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>

<h3>deep_xml: Model methods that utilize (but do not overwrite) to_xml</h3>
<p>I chose to write methods in the models that handled including the children&#8217;s xml such that a single call to my_record.full_xml would produce nested xml automatically.  Notice how the builder is being passed to the children, it&#8217;s important!</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">class</span> ParentClass <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
    has_many <span style="color:#ff3333; font-weight:bold;">:children</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> deep_xml<span style="color:#006600; font-weight:bold;">&#40;</span>builder=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      to_xml<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> builder<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
        children.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>child<span style="color:#006600; font-weight:bold;">|</span> child.<span style="color:#9900CC;">deep_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span>xml<span style="color:#006600; font-weight:bold;">&#41;</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>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">class</span> Child <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
    belongs_to <span style="color:#ff3333; font-weight:bold;">:parent</span>
    has_one <span style="color:#ff3333; font-weight:bold;">:grandchild</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> deep_xml<span style="color:#006600; font-weight:bold;">&#40;</span>builder=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      to_xml<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> builder, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
        grandchild.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</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>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">class</span> Grandchild <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
    belongs_to <span style="color:#ff3333; font-weight:bold;">:child</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Now the call is simple:</span>
Parent.<span style="color:#9900CC;">firstdeep_xml</span> <span style="color:#008000; font-style:italic;">#=&gt; custom xml for a parent that includes its </span>
                        <span style="color:#008000; font-style:italic;">#   children and their grandchildren (1 each in this case)</span></pre></div></div>

<p>There&#8217;s not much to it, but I found this solution to be nice shorthand that cleaned up ugly nested to_xml blocks I was writing over and over.  I call my_record.deep_xml from any layer of the family tree and return a nice drill down of data to the leaf children.  It&#8217;s great if you&#8217;re working with a complicated database and need to be able to present your data in xml.</p>
<h3>If you are so inclined&#8230;</h3>
<p>If you really need to, you can just overwrite the to_xml method in the model.  While fine to do if you know you&#8217;ll always want that one specific template, I avoid it as much as possible and won&#8217;t cover it since examples are all over the blogosphere.  Why not just make a separate function to avoid producing unexpected results for someone else who joins your project later on?</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/10/10/making-willpaginate-and-rails-to_xml-play-nice-with-activeresource/" rel="bookmark" class="crp_title">Making WillPaginate and Rails to_xml play nice with ActiveResource</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/11/multithreading-in-ruby-on-rails/" rel="bookmark" class="crp_title">Multithreading in Ruby on Rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/10/28/faking-a-will-paginate-collection-on-an-active-resource-model/" rel="bookmark" class="crp_title">Faking a Will Paginate Collection on an Active Resource model</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/" rel="bookmark" class="crp_title">Rails 2.3 Nested Object Forms: I&#8217;m not Crazy about Them</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/10/merging-a-has_many-relationship-into-one-instance/" rel="bookmark" class="crp_title">Merging a :has_many relationship into one instance</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Advanced Model Based searches in rails</title>
		<link>http://blog.smartlogicsolutions.com/2008/07/21/advanced-model-based-searches-in-rails/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/07/21/advanced-model-based-searches-in-rails/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 16:24:55 +0000</pubDate>
		<dc:creator>Scott Davis</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Scott Davis]]></category>
		<category><![CDATA[Advanced Search]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=102</guid>
		<description><![CDATA[After watching a railscast episode on advanced searching I thought I would give it a try. So I came up with a slightly modified version that would handle my search. Model class ExportSearch &#160; def timecards find_cards end &#160; def users&#40;u&#41; @u = u end &#160; def projects&#40;p&#41; @p = p end &#160; def tasks&#40;t&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>After watching a <a href="http://railscasts.com/episodes/111" target="_blank">railscast episode</a> on advanced searching I thought I would give it a try.  So I came up with a slightly modified version that would handle my search.</p>
<h3>Model</h3>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ExportSearch
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> timecards
    find_cards
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> users<span style="color:#006600; font-weight:bold;">&#40;</span>u<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@u</span> = u
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> projects<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">p</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    @<span style="color:#CC0066; font-weight:bold;">p</span> = <span style="color:#CC0066; font-weight:bold;">p</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> tasks<span style="color:#006600; font-weight:bold;">&#40;</span>t<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@t</span> = t
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> dates<span style="color:#006600; font-weight:bold;">&#40;</span>date1, date2<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@d1</span> = date1
    <span style="color:#0066ff; font-weight:bold;">@d2</span> = date2
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> clients<span style="color:#006600; font-weight:bold;">&#40;</span>c<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@c</span> = c
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
private
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> find_cards
    TimeCard.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> conditions, :<span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:task <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:project</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:date</span><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> projects_conditions
    <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;tasks.project_id IN (?)&quot;</span>, @<span style="color:#CC0066; font-weight:bold;">p</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> @<span style="color:#CC0066; font-weight:bold;">p</span>.<span style="color:#9900CC;">blank</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> client_conditions
    <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;projects.client_id IN (?)&quot;</span>, <span style="color:#0066ff; font-weight:bold;">@c</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@c</span>.<span style="color:#9900CC;">blank</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> date_conditions
    <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;date BETWEEN ? AND ?&quot;</span>, <span style="color:#0066ff; font-weight:bold;">@d1</span>, <span style="color:#0066ff; font-weight:bold;">@d2</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#006600; font-weight:bold;">&#40;</span>@d1.<span style="color:#9900CC;">blank</span>? <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#0066ff; font-weight:bold;">@d2</span>.<span style="color:#9900CC;">blank</span>?<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> task_conditions
    <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;task_id IN (?)&quot;</span>, <span style="color:#0066ff; font-weight:bold;">@t</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@t</span>.<span style="color:#9900CC;">blank</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> users_conditions
    <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;user_id IN (?)&quot;</span>, <span style="color:#0066ff; font-weight:bold;">@u</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@u</span>.<span style="color:#9900CC;">blank</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> conditions
    <span style="color:#006600; font-weight:bold;">&#91;</span>conditions_clauses.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">' AND '</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#006600; font-weight:bold;">*</span>conditions_options<span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> conditions_clauses
    conditions_parts.<span style="color:#9900CC;">map</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>condition<span style="color:#006600; font-weight:bold;">|</span> condition.<span style="color:#9900CC;">first</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> conditions_options
    conditions_parts.<span style="color:#9900CC;">map</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>condition<span style="color:#006600; font-weight:bold;">|</span> condition<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span>..<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">flatten</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> conditions_parts
    private_methods<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">grep</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>_conditions$<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>m<span style="color:#006600; font-weight:bold;">|</span> send<span style="color:#006600; font-weight:bold;">&#40;</span>m<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">compact</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3>Controller</h3>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    search = ExportSearch.<span style="color:#9900CC;">new</span>
    search.<span style="color:#9900CC;">users</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:export</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:users</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:export</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:users</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">blank</span>?
    search.<span style="color:#9900CC;">tasks</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:export</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:tasks</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:export</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:tasks</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">blank</span>?
    search.<span style="color:#9900CC;">projects</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:export</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:projects</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:export</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:projects</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">blank</span>?
    search.<span style="color:#9900CC;">dates</span><span style="color:#006600; font-weight:bold;">&#40;</span>start_date, end_date<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#0066ff; font-weight:bold;">@time_cards</span> = search.<span style="color:#9900CC;">timecards</span></pre></div></div>

<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/10/23/dry-up-your-controllers-with-find_or_redirect/" rel="bookmark" class="crp_title">DRY up your Controllers with find_or_redirect</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/10/merging-a-has_many-relationship-into-one-instance/" rel="bookmark" class="crp_title">Merging a :has_many relationship into one instance</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/11/multithreading-in-ruby-on-rails/" rel="bookmark" class="crp_title">Multithreading in Ruby on Rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/10/28/faking-a-will-paginate-collection-on-an-active-resource-model/" rel="bookmark" class="crp_title">Faking a Will Paginate Collection on an Active Resource model</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/05/mapresources-and-custom-nested-routes/" rel="bookmark" class="crp_title">map.resources and custom nested routes</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/07/21/advanced-model-based-searches-in-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Merging a :has_many relationship into one instance</title>
		<link>http://blog.smartlogicsolutions.com/2008/07/10/merging-a-has_many-relationship-into-one-instance/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/07/10/merging-a-has_many-relationship-into-one-instance/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 14:13:59 +0000</pubDate>
		<dc:creator>Joseph Jakuta</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Joseph Jakuta]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/2008/07/10/merging-a-has_many-relationship-into-one-instance/</guid>
		<description><![CDATA[So the problem is that I have an ActiveRecord model that has a :has_many relationship to another model (we&#8217;ll call this one object), but when I am in the view context I didn&#8217;t want to have to loop through the object each time to determine which data was being displayed. Object has many attributes (approximately [...]]]></description>
			<content:encoded><![CDATA[<p>So the problem is that I have an ActiveRecord model that has a :has_many relationship to another model (we&#8217;ll call this one object), but when I am in the view context I didn&#8217;t want to have to loop through the object each time to determine which data was being displayed.  Object has many attributes (approximately 30) and many are often null for a given instance. So I decided to add a method to my model to loop through all of objects and determine which data should be included.  Pretty much the rule was that if there was no data for a particular attribute temporarily save it to a copy of the object and then return that.  This is what I came up with.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> object
    tmp = objects.<span style="color:#9900CC;">first</span>
    objects.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>o<span style="color:#006600; font-weight:bold;">|</span> tmp.<span style="color:#9900CC;">attributes</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>key, value<span style="color:#006600; font-weight:bold;">|</span> tmp<span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span> = o<span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> value.<span style="color:#9900CC;">blank</span>? <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> key != <span style="color:#996600;">'id'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    tmp.<span style="color:#9900CC;">freeze</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>However there was a flaw here.  Every time I would view the page all of the data in the objects was getting overwritten with one copy of it.  After banging my head on the desk it was realized that tmp[key] = o[key] was actually writing the changes to the database permanently rewriting all of the objects (which still seems counter intuitive to me, because it seems like only the first record should have been the one changing).  But the solution was pretty simple.  The working method is as follows.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> object
    tmp = <span style="color:#CC00FF; font-weight:bold;">Object</span>.<span style="color:#9900CC;">new</span>
    objects.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>o<span style="color:#006600; font-weight:bold;">|</span> tmp.<span style="color:#9900CC;">attributes</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>key, value<span style="color:#006600; font-weight:bold;">|</span> tmp<span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span> = o<span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> value.<span style="color:#9900CC;">blank</span>? <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> key != <span style="color:#996600;">'id'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    tmp.<span style="color:#9900CC;">freeze</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/06/23/dont-abuse-the-session/" rel="bookmark" class="crp_title">Don&#8217;t Abuse the Session</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/" rel="bookmark" class="crp_title">Using ActiveRecord&#8217;s to_xml to produce custom xml including deep level associations</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/21/advanced-model-based-searches-in-rails/" rel="bookmark" class="crp_title">Advanced Model Based searches in rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/09/07/nicks-highlights-from-ruby-hoedown/" rel="bookmark" class="crp_title">Nick&#8217;s Highlights from Ruby Hoedown</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/11/losing-data-drag-and-drop-custom-class-flex-serialization/" rel="bookmark" class="crp_title">Losing Data When Drag and Dropping Custom Classes in Flex?</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/07/10/merging-a-has_many-relationship-into-one-instance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft WebDav opens document as Read-Only when using RailsDav</title>
		<link>http://blog.smartlogicsolutions.com/2008/07/01/microsoft-webdav-opens-document-as-read-only-when-using-railsdav/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/07/01/microsoft-webdav-opens-document-as-read-only-when-using-railsdav/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 20:49:55 +0000</pubDate>
		<dc:creator>Joseph Jakuta</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Joseph Jakuta]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[WebDav]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/2008/07/01/microsoft-webdav-opens-document-as-read-only-when-using-railsdav/</guid>
		<description><![CDATA[I had been working on a project in which we wanted to utilize WebDAV (namely for editing Word &#038; Excel  Documents that were saved in our application).  In order to do this we decided to use a plugin from <a href="http://liverail.net" target="_new">liverail.net</a> that can be found <a href="http://www.liverail.net/articles/2006/06/25/webdav-ruby-on-rails-plugin" target="_new">here</a>.  It was pretty easy to hook up after a little direction from a guy over at Benryan Inc [apologies I cannot find a link for them], but there was a major issue. When opening a document through the ActiveX controller for editing it was opening in Read-Only mode.  

After a few starts and stops, many hours of reading through the <a href="http://www.webdav.org/" target="_new">webdav documentation</a>, and browsing through the http traffic using <a href="http://www.fiddlertool.com/fiddler/" target="_new">Fiddler</a> - it was determined that locking was the issue.]]></description>
			<content:encoded><![CDATA[<p>I had been working on a project in which we wanted to utilize WebDAV (namely for editing Word &#038; Excel  Documents that were saved in our application).  In order to do this we decided to use a plugin from <a href="http://liverail.net" target="_new">liverail.net</a> that can be found <a href="http://www.liverail.net/articles/2006/06/25/webdav-ruby-on-rails-plugin" target="_new">here</a>.  It was pretty easy to hook up after a little direction from a guy over at Benryan Inc [apologies I cannot find a link for them], but there was a major issue. When opening a document through the ActiveX controller for editing it was opening in Read-Only mode.  </p>
<p>After a few starts and stops, many hours of reading through the <a href="http://www.webdav.org/" target="_new">webdav documentation</a>, and browsing through the http traffic using <a href="http://www.fiddlertool.com/fiddler/" target="_new">Fiddler</a> &#8211; it was determined that locking was the issue.</p>
<p><span id="more-54"></span></p>
<p>What I found in the RailsDav plugin is that the implementation of locking is as follows (lines 92-100 of railsdav/act_as_railsdav.rb):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> webdav_lock<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;">#TODO implementation for now return a 200 OK</span>
    render <span style="color:#ff3333; font-weight:bold;">:nothing</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">200</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0000FF; font-weight:bold;">return</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> webdav_unlock<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;">#TODO implementation for now return a 200 OK</span>
    render <span style="color:#ff3333; font-weight:bold;">:nothing</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">200</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0000FF; font-weight:bold;">return</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>However, Microsoft actually won&#8217;t let you edit a document with such lax locking.  So I rewrote the lock method so that it returned a valid lock.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> webdav_lock<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
     <span style="color:#0066ff; font-weight:bold;">@lock</span> = get_lock<span style="color:#006600; font-weight:bold;">&#40;</span>@path_info<span style="color:#006600; font-weight:bold;">&#41;</span>
     <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@lock</span>
         response.<span style="color:#9900CC;">headers</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Lock-Token&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;&lt;#{@lock.token}&gt;&quot;</span>
         response.<span style="color:#9900CC;">headers</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Content-Type&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'text/xml; charset=&quot;utf-8&quot;'</span>
         render <span style="color:#ff3333; font-weight:bold;">:inline</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">lock_xml</span>, <span style="color:#ff3333; font-weight:bold;">:layout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>, <span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:rxml</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">200</span>  <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0000FF; font-weight:bold;">return</span>
       <span style="color:#9966CC; font-weight:bold;">else</span>
         render  <span style="color:#ff3333; font-weight:bold;">:nothing</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#6666ff; font-weight:bold;">WebDavErrors::ForbiddenError</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0000FF; font-weight:bold;">return</span>
       <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>There were a few other pieces of code that were needed to get this working though.  Namely the .lock_xml method, and get_lock.  Let&#8217;s tackle them each in turn.</p>
<p>In railsdav/propxml.rb you can find the XML structures for the PROPFIND and the PROPPATCH methods for WebDAV.  However both locking and unlocking require their own structures.  So I added one for locking.  It is as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> lock_xml
<span style="color:#006600; font-weight:bold;">&lt;&amp;</span>lt;EOPROPFIND_XML 
         xml.<span style="color:#9900CC;">D</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:multistatus</span>, <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;xmlns:D&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;DAV:&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
           xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:lockdiscovery</span> <span style="color:#9966CC; font-weight:bold;">do</span>
             xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:activelock</span> <span style="color:#9966CC; font-weight:bold;">do</span>
               xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:locktype</span> <span style="color:#9966CC; font-weight:bold;">do</span> 
                 xml.<span style="color:#9900CC;">D</span> <span style="color:#0066ff; font-weight:bold;">@lock</span>.<span style="color:#9900CC;">type</span>.<span style="color:#9900CC;">to_sym</span>
               <span style="color:#9966CC; font-weight:bold;">end</span>
               xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:lockscope</span> <span style="color:#9966CC; font-weight:bold;">do</span> 
                 xml.<span style="color:#9900CC;">D</span> <span style="color:#0066ff; font-weight:bold;">@lock</span>.<span style="color:#9900CC;">scope</span>.<span style="color:#9900CC;">to_sym</span>
               <span style="color:#9966CC; font-weight:bold;">end</span>
               xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:depth</span>, <span style="color:#0066ff; font-weight:bold;">@lock</span>.<span style="color:#9900CC;">depth</span>
               xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:timeout</span>, <span style="color:#0066ff; font-weight:bold;">@lock</span>.<span style="color:#9900CC;">timeout_full</span>               
               xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:locktoken</span> <span style="color:#9966CC; font-weight:bold;">do</span> 
                 xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:href</span>, <span style="color:#0066ff; font-weight:bold;">@lock</span>.<span style="color:#9900CC;">token</span>
               <span style="color:#9966CC; font-weight:bold;">end</span>               
               xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:lockroot</span> <span style="color:#9966CC; font-weight:bold;">do</span> 
                 xml.<span style="color:#9900CC;">D</span> <span style="color:#ff3333; font-weight:bold;">:href</span>, <span style="color:#0066ff; font-weight:bold;">@lock</span>.<span style="color:#9900CC;">href</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>
         <span style="color:#9966CC; font-weight:bold;">end</span>  
EOPROPFIND_XML
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Then there is the get_lock method.  Writing get_lock was a two step process.  If you look at (lines 269-287 of railsdav/act_as_railsdav.rb) you can see several methods that are very similar in function to their respective purposes.  So I began by simply adding the following in this section:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> get_lock<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#6666ff; font-weight:bold;">WebDavErrors::ForbiddenError</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Then in my application&#8217;s controller that overrides all of the acts_as_railsdav methods I did just that:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> get_lock<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#9966CC; font-weight:bold;">unless</span> get_resource_for_path<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">locked</span>?
    <span style="color:#0000FF; font-weight:bold;">return</span> ActiveRecordLock.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#123;</span>:type <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'write'</span>, <span style="color:#ff3333; font-weight:bold;">:scope</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'exclusive'</span>, <span style="color:#ff3333; font-weight:bold;">:timeout</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">60</span><span style="color:#006600; font-weight:bold;">*</span><span style="color:#006666;">60</span><span style="color:#006600; font-weight:bold;">*</span><span style="color:#006666;">5</span>, <span style="color:#ff3333; font-weight:bold;">:href</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> path, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#006666;">4</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So now you&#8217;ll notice two new things that need coding here.  The .locked? method for the resource and ActiveRecordLock.  We decided to not worry about multiple users editing the same document at the same time on this project.  Because of this and the time constraints .locked? simply returns true.  If one were to deal with unlocking at some point this would have to be come a check to the database or something to make sure that the document is indeed unlocked.  The same goes for ActiveRecordLock.  It really just deals with the flat information needed by the Lock XML and not saving it to check if it is locked later on.  Maybe someday, somebody will undertake that task I suppose.  Anyway, here is what I had for the portion of the ActiveRecordLock model that I needed.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ActiveRecordLock
   attr_accessor <span style="color:#ff3333; font-weight:bold;">:type</span>, <span style="color:#ff3333; font-weight:bold;">:scope</span>, <span style="color:#ff3333; font-weight:bold;">:timeout</span>, <span style="color:#ff3333; font-weight:bold;">:depth</span>, <span style="color:#ff3333; font-weight:bold;">:timeout_units</span>, <span style="color:#ff3333; font-weight:bold;">:href</span>, <span style="color:#ff3333; font-weight:bold;">:token</span>
&nbsp;
   <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>      
      <span style="color:#0066ff; font-weight:bold;">@type</span>    = args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:type</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#0066ff; font-weight:bold;">@scope</span>   = args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:scope</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#0066ff; font-weight:bold;">@timeout</span> = args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:timeout</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#0066ff; font-weight:bold;">@href</span>    = args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span>  
      <span style="color:#0066ff; font-weight:bold;">@depth</span>   = <span style="color:#996600;">'Infinity'</span>
      <span style="color:#0066ff; font-weight:bold;">@timeout_units</span> = <span style="color:#996600;">'Second'</span>
      <span style="color:#0066ff; font-weight:bold;">@token</span>   = build_token<span style="color:#006600; font-weight:bold;">&#40;</span>args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><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> timeout_full
     <span style="color:#996600;">&quot;#{self.timeout_units}-#{self.timeout}&quot;</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
   protected
     <span style="color:#9966CC; font-weight:bold;">def</span> build_token<span style="color:#006600; font-weight:bold;">&#40;</span>text<span style="color:#006600; font-weight:bold;">&#41;</span>
       <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'digest/md5'</span>
       md5 = <span style="color:#6666ff; font-weight:bold;">Digest::MD5</span>.<span style="color:#9900CC;">hexdigest</span><span style="color:#006600; font-weight:bold;">&#40;</span>text.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span>
       <span style="color:#996600;">'opaquelocktoken:'</span><span style="color:#006600; font-weight:bold;">+</span>md5<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>,<span style="color:#006666;">7</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">'-'</span><span style="color:#006600; font-weight:bold;">+</span>md5<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">8</span>,<span style="color:#006666;">11</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">'-'</span><span style="color:#006600; font-weight:bold;">+</span>md5<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">12</span>,<span style="color:#006666;">15</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">'-'</span><span style="color:#006600; font-weight:bold;">+</span>md5<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">16</span>,<span style="color:#006666;">19</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">'-'</span><span style="color:#006600; font-weight:bold;">+</span>md5<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">20</span>,<span style="color:#006666;">31</span><span style="color:#006600; font-weight:bold;">&#93;</span>
     <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>There is still plenty that needs to be done to get the full lock/unlock, but hopefully this will get someone started and save a few headaches.  </p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/07/09/reading-and-replacing-text-in-word-docx-and-excel-xlsx-documents-using-ruby/" rel="bookmark" class="crp_title">Reading and replacing text in Word DocX and Excel XlsX documents using Ruby</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/10/10/making-willpaginate-and-rails-to_xml-play-nice-with-activeresource/" rel="bookmark" class="crp_title">Making WillPaginate and Rails to_xml play nice with ActiveResource</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/" rel="bookmark" class="crp_title">Using ActiveRecord&#8217;s to_xml to produce custom xml including deep level associations</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/10/23/dry-up-your-controllers-with-find_or_redirect/" rel="bookmark" class="crp_title">DRY up your Controllers with find_or_redirect</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/21/advanced-model-based-searches-in-rails/" rel="bookmark" class="crp_title">Advanced Model Based searches in rails</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/07/01/microsoft-webdav-opens-document-as-read-only-when-using-railsdav/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rails 2.1 broke my mysql foreign keys!</title>
		<link>http://blog.smartlogicsolutions.com/2008/06/24/rails-21-broke-my-mysql-foreign-keys/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/06/24/rails-21-broke-my-mysql-foreign-keys/#comments</comments>
		<pubDate>Tue, 24 Jun 2008 21:03:36 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/2008/06/24/rails-21-broke-my-mysql-foreign-keys/</guid>
		<description><![CDATA[Rails 2.1 introduced in the MySQL Adapter &#8220;smart integer columns.&#8221; The idea was to use the :limit option to determine whether a smallint, int, or bigint should be used. This is something that the Postgres adapter had already previously implemented. The relevant code in activerecord/lib/active_record/connection_adapters/mysql_adapter.rb is: # Maps logical Rails types to MySQL-specific data types. [...]]]></description>
			<content:encoded><![CDATA[<p>Rails 2.1 introduced in the MySQL Adapter &#8220;smart integer columns.&#8221;  The idea was to use the :limit option to determine whether a smallint, int, or bigint should be used.  This is something that the Postgres adapter had already previously implemented.  The relevant code in activerecord/lib/active_record/connection_adapters/mysql_adapter.rb is:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#008000; font-style:italic;"># Maps logical Rails types to MySQL-specific data types.</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> type_to_sql<span style="color:#006600; font-weight:bold;">&#40;</span>type, limit = <span style="color:#0000FF; font-weight:bold;">nil</span>, precision = <span style="color:#0000FF; font-weight:bold;">nil</span>, scale = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">super</span> <span style="color:#9966CC; font-weight:bold;">unless</span> type.<span style="color:#9900CC;">to_s</span> == <span style="color:#996600;">'integer'</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">case</span> limit
    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">0</span>..<span style="color:#006666;">3</span>
      <span style="color:#996600;">&quot;smallint(#{limit})&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">4</span>..<span style="color:#006666;">8</span>
      <span style="color:#996600;">&quot;int(#{limit})&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">9</span>..<span style="color:#006666;">20</span>
      <span style="color:#996600;">&quot;bigint(#{limit})&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#996600;">'int(11)'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Mirko Froehlich <a href="http://rails.lighthouseapp.com/projects/8994/tickets/55-remove-default-integer-limit-from-mysqladapter-native_database_types">suggests monkey patching this function</a>.  Timothy Jones <a href="http://timothynjones.wordpress.com/2008/06/10/change-to-activerecord-mysql-adapter-breaks-tests/">blogged about it</a>.</p>
<p>To monkey-patch this, just drop a file (fix_mysql_adapter.rb) into your initializers/ directory, as such:</p>
<p><span id="more-53"></span></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> ActiveRecord
  <span style="color:#9966CC; font-weight:bold;">module</span> ConnectionAdapters
    <span style="color:#9966CC; font-weight:bold;">class</span> MysqlAdapter <span style="color:#006600; font-weight:bold;">&lt;</span> AbstractAdapter
      <span style="color:#008000; font-style:italic;"># Maps logical Rails types to MySQL-specific data types.</span>
      <span style="color:#9966CC; font-weight:bold;">def</span> type_to_sql<span style="color:#006600; font-weight:bold;">&#40;</span>type, limit = <span style="color:#0000FF; font-weight:bold;">nil</span>, precision = <span style="color:#0000FF; font-weight:bold;">nil</span>, scale = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">super</span> <span style="color:#9966CC; font-weight:bold;">unless</span> type.<span style="color:#9900CC;">to_s</span> == <span style="color:#996600;">'integer'</span>
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">case</span> limit
        <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">0</span>..<span style="color:#006666;">3</span>
          <span style="color:#996600;">&quot;smallint(#{limit})&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">4</span>..<span style="color:#006666;">11</span>
          <span style="color:#996600;">&quot;int(#{limit})&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">12</span>..<span style="color:#006666;">20</span>
          <span style="color:#996600;">&quot;bigint(#{limit})&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">else</span>
          <span style="color:#996600;">'int(11)'</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>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>All we&#8217;ve done is change how the mysql adapter interprets the limit attribute.  In my opinion, this isn&#8217;t a particularly great solution, as it&#8217;s more appropriate for non-foreign key integers to behave as the rails team suggested.  This really only affects us when we&#8217;re dealing with foreign keys, because mysql enforces our column types to match.</p>
<p><strong>The Real Problem</strong><br />
So, if the problem isn&#8217;t here, where is it?  The problem actually lies in the schema dumper.  Notice in the previous code samples the else clause in the case statement.  If limit is nil (or outside of 0..20), then this falls back to int(11).  Curiously, when I have a migration such as the following, the schema dumper adds a :limit => 11, even though I didn&#8217;t specify it!</p>
<pre>
$> rails test -d mysql
$> cd test
$> ruby script/generate model user name:string
$> ruby script/generate model game name:string user_id:integer
$> rake db:create db:migrate
</pre>
<p>First, let&#8217;s check our game migration to verify that it doesn&#8217;t specify :limit => 11.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> CreateGames <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Migration</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">up</span>
    create_table <span style="color:#ff3333; font-weight:bold;">:games</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
      t.<span style="color:#CC0066; font-weight:bold;">string</span> <span style="color:#ff3333; font-weight:bold;">:name</span>
      t.<span style="color:#CC0066; font-weight:bold;">integer</span> <span style="color:#ff3333; font-weight:bold;">:user_id</span>
&nbsp;
      t.<span style="color:#9900CC;">timestamps</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">down</span>
    drop_table <span style="color:#ff3333; font-weight:bold;">:games</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So, there&#8217;s no limit specified.  But let&#8217;s take a look at schema.rb.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">ActiveRecord::Schema</span>.<span style="color:#9900CC;">define</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:version</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">20080624161220</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  create_table <span style="color:#996600;">&quot;games&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:force</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;name&quot;</span>
    t.<span style="color:#CC0066; font-weight:bold;">integer</span>  <span style="color:#996600;">&quot;user_id&quot;</span>,    <span style="color:#ff3333; font-weight:bold;">:limit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">11</span>
    t.<span style="color:#9900CC;">datetime</span> <span style="color:#996600;">&quot;created_at&quot;</span>
    t.<span style="color:#9900CC;">datetime</span> <span style="color:#996600;">&quot;updated_at&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  create_table <span style="color:#996600;">&quot;users&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:force</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;name&quot;</span>
    t.<span style="color:#9900CC;">datetime</span> <span style="color:#996600;">&quot;created_at&quot;</span>
    t.<span style="color:#9900CC;">datetime</span> <span style="color:#996600;">&quot;updated_at&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Ah ha!  Where&#8217;d that :limit => 11 come from?  The schema generator!!!  This is our culprit.  We need to isolate the schema generation code, and ensure that isn&#8217;t forcing :limit => 11 onto our integers that don&#8217;t explicitly set a limit.</p>
<p>As I started down this track, I hooked up with Rob Sterner from <a href="http://itasoftware.com">ITA Software</a> on IRC.  He filed the <a href="http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/463">original ticket</a>.  By the time I got in touch with him, he pretty much had the problem solved.</p>
<p>First, let&#8217;s fully illustrate the problem.  When you run migrations, naked integer statements</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">t.<span style="color:#CC0066; font-weight:bold;">integer</span> <span style="color:#ff3333; font-weight:bold;">:myvalue</span></pre></div></div>

<p>are inserted into the database with :limit => 11 (this is handled by the extract_limit() function in the adapters).  SchemaDumper.dump is called after your migrations are finished, and creates schema.rb by inspecting the database (not your migrations &#8212; which makes sense).  However, when extracting the information from the database, the SchemaDumper picks up this limit of 11, which causes it to write this out in your schema.rb file:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">t.<span style="color:#CC0066; font-weight:bold;">integer</span> <span style="color:#ff3333; font-weight:bold;">:myvalue</span>, <span style="color:#ff3333; font-weight:bold;">:limit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">11</span></pre></div></div>

<p>See a problem?  Yup, where in our migration we did not explicitly set a limit, the SchemaDumper did!</p>
<p><strong>The Solution</strong><br />
So what&#8217;s the solution?  Well, what we need to do is alter SchemaDumper to identify int(11), and special case the output (so that :limit => 11 is not appended).  At first, this seemed very hacky to me.  What if I want a bigint(11) and not int(11)?  Well, turns out this isn&#8217;t a valid concern.  Why?  If we really wanted bigint(11), our migration would look different:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">t.<span style="color:#CC0066; font-weight:bold;">integer</span> <span style="color:#ff3333; font-weight:bold;">:myvalue</span>, <span style="color:#ff3333; font-weight:bold;">:limit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">11</span></pre></div></div>

<p>So, when migrations are run, this field would be placed into the database as a bigint(11) column.  And, when SchemaDumper encounters it, it will also see it as bigint(11),  As long as our special case discriminates between bigint(11) and int(11), then we&#8217;re in the clear!  The fact is, in rails 2.1, there&#8217;s no way to get an int(11) column in mysql unless you&#8217;ve left off the :limit in your migration.</p>
<p><strong>Where&#8217;s the patch?</strong><br />
Funny (read: agonizing) story&#8230;..we were testing all of this against 2.1.0.  When we checked out edge rails, all of this code had changed!!!  In fact, looks like Jeremy Kemper (bitsweat) already fixed it.</p>
<p>For the sake of completeness, I&#8217;m including the patch that Rob threw together that does the trick for 2.1.0.  This patch applied to /activerecord-2.1.0/lib/active_record/connection_adapters/mysql_adapter.rb does the trick.</p>
<pre>
127c127,129
<           else
---
>           elsif sql_type == 'int(11)'
>             nil # special case for :integer columns w/ no explicit :limit set in their migration
>           else
</pre>
<p><strong>The Lesson</strong><br />
Check out edge rails to make sure that the problem is still unresolved before you spend all day on something!!!</p>
<p>Also, be aware that edge has changed the meaning of :limit.  See <a href="http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/463">the ticket</a> for Jeremy&#8217;s explanation.  Up through Rails 2.1, the :limit attribute for integers dictated the display width.  In other words, it did not specify the storage size, but rather the amount of space mysql would use to display it when returning query results.  Moving forward, it will be used to indicate the number of bytes to use for storage.  Rails will now effectively use tinyint (1), smallint (2), mediumint (3), int (4) and bigint (8).  So, prepare yourselves accordingly.</p>
<p>Special thanks to Rob Sterner for spending lots of time today working through this with me.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/06/13/ruby-on-rails-polymorphic-association-benchmarks/" rel="bookmark" class="crp_title">Ruby on Rails Polymorphic Association Benchmarks</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/10/10/making-willpaginate-and-rails-to_xml-play-nice-with-activeresource/" rel="bookmark" class="crp_title">Making WillPaginate and Rails to_xml play nice with ActiveResource</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/10/28/faking-a-will-paginate-collection-on-an-active-resource-model/" rel="bookmark" class="crp_title">Faking a Will Paginate Collection on an Active Resource model</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/05/sexier-migrations-in-rails-21/" rel="bookmark" class="crp_title">Sexier Migrations in Rails 2.1</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/11/problems-with-restful_authentication-plugin-and-internet-explorer-cookies/" rel="bookmark" class="crp_title">Problems with restful_authentication Plugin and Internet Explorer Cookies</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/06/24/rails-21-broke-my-mysql-foreign-keys/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

