<?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>Yesterday's Thoughts &#187; Ruby on Rails</title>
	<atom:link href="http://www.warmroom.com/yesterdays/category/software-internet/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.warmroom.com</link>
	<description>Reflections on family life, software, politics and endurance sports.</description>
	<lastBuildDate>Sat, 10 Sep 2011 20:46:58 +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>An Enhancement for ri</title>
		<link>http://www.warmroom.com/yesterdays/2008/11/15/an-enhancement-for-ri/</link>
		<comments>http://www.warmroom.com/yesterdays/2008/11/15/an-enhancement-for-ri/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 18:53:11 +0000</pubDate>
		<dc:creator>Ray Baxter</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.warmroom.com/?p=234</guid>
		<description><![CDATA[Ruby Documentation is terse and difficult to navigate. There are some web based solutions, but I am not always on the web, and there are some solutions for keeping your local documentation up to date, but I haven&#8217;t automated them. Ri is the Ruby solution to this problem but the results are not always what [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby Documentation is terse and difficult to navigate. There are some web based solutions, but I am not always on the web, and there are some solutions for keeping your local documentation up to date, but I haven&#8217;t automated them.</p>
<p>Ri is the Ruby solution to this problem but the results are not always what you are expecting.</p>
<p><a href="http://danielchoi.com/software/ri-enhanced.html">A Simple Enhancement for ri</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.warmroom.com/yesterdays/2008/11/15/an-enhancement-for-ri/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bug &amp; Patch for acts_as_ferret</title>
		<link>http://www.warmroom.com/yesterdays/2006/05/23/bug-patch-for-acts_as_ferret/</link>
		<comments>http://www.warmroom.com/yesterdays/2006/05/23/bug-patch-for-acts_as_ferret/#comments</comments>
		<pubDate>Wed, 24 May 2006 05:49:51 +0000</pubDate>
		<dc:creator>Ray Baxter</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.warmroom.com/yesterdays/2006/05/23/bug-patch-for-acts_as_ferret/</guid>
		<description><![CDATA[I&#8217;m putting the finishing touches on Endurance Central. Basically the UI is done and all of the user functionality is complete, if not yet fully exposed. I have started to collect race data (the current data on the site is unreliable test data &#8211; I need to clear that out). One of the last features [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m putting the finishing touches on <a href="http://endurancecentral.com/">Endurance Central</a>. Basically the UI is done and all of the user functionality is complete, if not yet fully exposed. I have started to collect race data (the current data on the site is unreliable test data &#8211; I need to clear that out).</p>
<p>One of the last features that I added was to make it possible for users to report inaccurate data. This feature was important to the community aspect of the site and is the bridge to get users into the membership system and to take some of the responsiblity for the content off of me.</p>
<p>I allowed the user to report an error on any event. To do this, I subclassed by Event model into LiveEvents (those you see) and EventCorrections, and then I created an administrative interface to accept or reject corrections in the EventCorrections. With Rails and Ruby this was brilliantly easy; using single table inheritance, it took less time to do than it had taken me to think about it and almost every point worked on the first pass.</p>
<p>But, and you knew there was going to be a &#8220;but&#8221; didn&#8217;t you, this somehow broke by search function for the site. <span id="more-161"></span>Search had also been extremely simple to implement. I used <a href="http://ferret.davebalmain.com/trac/wiki/">Ferret</a> in combination with the <a href="http://projects.jkraemer.net/acts_as_ferret">acts_as_ferret</a> plugin for Rails. Somehow when I moves to LiveEvents from Events, searches that returned no results, broke, throwing mysterious exceptions without and traces.</p>
<p>I didn&#8217;t have a test for this case (I was still testing the base Events class &#8211; doh!) so I only saw it occassionally in development, but when I started seeing it  in my production code, I tracked it down. I thought that it was from an upgrade to acts_as_ferret from a few weeks ago. Nope. I somehow caught</p>
<p>Here is the relevant bit of acts_as_ferret.</p>
<pre>def find_by_contents(q, options = {}
   id_array = [] scores_by_id = {}
   find_id_by_contents(q, options) do |element|
     id_array < < id = element[:id].to_i
     scores_by_id[id] = element[:score]
   end
   begin
      if self.superclass == ActiveRecord::Base
        result = self.find(id_array)
      else
        # no direct subclass of Base --> STI
        # TODO: AR will filter out hits from other classes for us, but this
        # will lead to less results retrieved --> scoping of ferret query
        # to self.class is still needed.
        if id_array.empty?
          result = []
        else
           result = self.find(:all, find_options.merge(:conditions => ["id in (?)",id_array]))
        end
     end
  rescue
     logger.debug "REBUILD YOUR INDEX! One of the id's didn't have an associated record: #{id_array}"
   end

   # sort results by score (descending)
   result.sort! { |b, a| scores_by_id[a.id] < => scores_by_id[b.id] }

   logger.debug "Query: #{q}nResult id_array: #{id_array.inspect},nresult: #{result},nscores: #{scores_by_id.inspect}"

   return result
end
</pre>
<p>I don&#8217;t really understand the comment, &#8220;no direct subclass of Base &#8211;&gt; STI TODO: etc.&#8221;  It seems like using the AR filtering would be a good thing in all cases. Maybe this would break paginate? Anyway, I was seeing the logger.debug in dev, but I had misattributed it to some manual interventions that I had made in the db to remove some old data. Wrong.</p>
<p>The problem was that by changing my model to STI, the LiveEvent was not a subclass of ActiveRecord::Base, so instead of using the well-behaved <code>return = self.find(id_array)</code> my queries were now going through the ill-behaved <code>return = self.find(:all, :conditions =&amp;gt; ["id in (?)",id_array])</code>. Calling <code>find</code> with any empty array returns an empty array. Calling <code>find</code> with condtions and a nil argument throws an exception.</p>
<p>Since this exception is caught, without doing anything worthwhile, the value of return is nil. Calling sort! on nil a few lines later throws an error, but since this code is in a plugin, there is no usable trace.</p>
<p>Lessons:</p>
<ul>
<li>Refactor the tests at the same time as code.</li>
<li>Don&#8217;t allow errors in the logs. These always came up when I was working on something unrelated, so I never took the time to track them down.</li>
<li>Anticipate the edge conditions. Seriously, 0 results is not unlikely.</li>
</ul>
<hr />I filed a <a href="http://projects.jkraemer.net/acts_as_ferret/ticket/18">ticket</a> on acts_as_ferret and included a patch.There were a couple of ways I could have gone with the patch.</p>
<ol>
<li>Added <code>return = [] </code> to the rescue.</li>
<li>Wrap the sort in a test for return.nil?</li>
<li>Initialize <code>return = []</code> at the top.</li>
<li>Add another condition within the block, <code>if id_array.size == 0 return = [] elsif self.superclass ...</code></li>
</ol>
<p>I actually did all of these in that order. They all worked in my tests. I decided on #4 because it was the most contained patch and had the added benefit of skipping the <code>find(id_array)</code> if the id_array was empty. Saving a db call isn&#8217;t something I would have gone out of my way to do without a strong motivation, but it was a side benefit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.warmroom.com/yesterdays/2006/05/23/bug-patch-for-acts_as_ferret/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bug in acts_as_authenticated</title>
		<link>http://www.warmroom.com/yesterdays/2006/02/21/bug-in-acts_as_authenticated/</link>
		<comments>http://www.warmroom.com/yesterdays/2006/02/21/bug-in-acts_as_authenticated/#comments</comments>
		<pubDate>Tue, 21 Feb 2006 16:55:03 +0000</pubDate>
		<dc:creator>Ray Baxter</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.warmroom.com/wordpress/?p=153</guid>
		<description><![CDATA[I found a bug in the acts_as_authenticated plugin. The activate method in User fails to update the user record when using both activate and 2-way reversible encryption. The symptom that I was is that @user.save was false in the controller. It fails at this line: update_attributes(:activated_at =&#38;gt; Time.now.utc, :activation_code =&#38;gt; nil) This fails because there [...]]]></description>
			<content:encoded><![CDATA[<p>I found a bug in the <a href="http://techno-weenie.net/svn/projects/plugins/acts_as_authenticated/">acts_as_authenticated</a> plugin. The activate method in User fails to update the user record when using both activate and 2-way reversible encryption. The symptom that I was is that @user.save was false in the controller.</p>
<p>It fails at this line:</p>
<pre><code>update_attributes(:activated_at =&amp;gt; Time.now.utc, :activation_code =&amp;gt; nil)</code></pre>
<p>This fails because there are a series of validations on saving the model. These on save validations on password_confirmation work (assuming correct values) when the user is created and when the password is changed, but fail on other saves of the user, particularly on activation, but would also fail if acts_as_authenticated had an edit method, or a last_seen method, or any other method that changed the user without also changing the password with a confirmation.</p>
<p>The <a href="http://wiki.rubyonrails.org/rails/pages/Acts_as_authenticated">rails wiki</a> has a proposed <a href="http://rails.techno-weenie.net/question/2006/1/18/user_activation_in_acts_as_authenticated  ">fix</a>, which works for activate only if not also using 2-way reversible encryption. The fix causes these validations to be attempted only if password_required, which in turn tests if password.blank? is false. </p>
<p>Two-way reversible encryption populates the model with the value of password, so that password.blank? is always false and password_required is always true. </p>
<p>I resolved the problem in acts_as_authenticated by making the following changes:</p>
<pre><code>validates_presence_of :password_confirmation, 
                 :if =&amp;gt; :confirmation_required? # not :password_required
validates_confirmation_of :password, 
                 :if =&amp;gt; :confirmation_required? #ditto
</code></pre>
<p>And then I added the following:</p>
<pre><code>after_save '@confirm_password = false'
	
def initialize(attributes = nil)
  super
  @confirm_password = true
end

def change_password(pass, confirm = nil)
  self.password = pass
  self.password_confirmation = confirm.nil? ? pass : confirm
  @confirm_password = true
end

protected

def confirmation_required?
  @confirm_password
end
</code></pre>
<p>Hope that helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.warmroom.com/yesterdays/2006/02/21/bug-in-acts_as_authenticated/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Another Good Thing about Rails</title>
		<link>http://www.warmroom.com/yesterdays/2005/09/22/another-good-thing-about-rails/</link>
		<comments>http://www.warmroom.com/yesterdays/2005/09/22/another-good-thing-about-rails/#comments</comments>
		<pubDate>Thu, 22 Sep 2005 16:09:01 +0000</pubDate>
		<dc:creator>Ray Baxter</dc:creator>
				<category><![CDATA[Communities]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.warmroom.com/wordpress/?p=130</guid>
		<description><![CDATA[There are many excellent features of Ruby on Rails. The technology has significant advantages for rapid development and deployment and I don&#8217;t think that I could undertake the work that I am doing to develop factscollector without it. I can prototype rapidly, and deploy the simplest thing that could possibly work. My plan is that [...]]]></description>
			<content:encoded><![CDATA[<p>There are many excellent features of Ruby on Rails. The technology has significant advantages for rapid development and deployment and I don&#8217;t think that I could undertake the work that I am doing to develop factscollector without it. I can prototype rapidly, and deploy the simplest thing that could possibly work. My plan is that this will also make it possible to incorporate user feedback and develop and deploy new features quickly. The software is simple and the one drawback that people often point to, &#8220;will it scale&#8221; is irrelevant to me. My design will scale, so I am not concerned about the framework scaling for me.</p>
<p>One aspect of Rails that hasn&#8217;t received that much attention from outsiders is the quality of the community. </p>
<p>I have been hanging out on the Ruby on Rails mailing list (<a href="http://news.gmane.org/gmane.comp.lang.ruby.rails">archive</a>). It is a great resource. Essentially everyone who has ever contributed to Rails and representatives of most of the major sites that have been deployed using Rails are regular contributors. The newest newbies hang out right next to them. It is a fascinating community.</p>
<p>There are about a hundred of messages a day, and dozens of new threads. Topics range from I&#8217;m having trouble installing on my platform  to this feature is planned for version 1.0 to submit a patch. This is the full gamut of possibilities. There is really very little snipping or flamage. The only heated discussions that I can remember in the 6 or more months that I have been on the list  have been about the rails pluralization conventions.</p>
<p>The interesting thing is that this list is a real community. One of the reasons for that is the care that people have exerted over the list. In regard to someone suggesting downloading a pirated copy of Agile Web Development with Rails pdf, <a href="http://www.loudthinking.com/">David Heinemeier Hansson</a> <a href="http://article.gmane.org/gmane.comp.lang.ruby.rails/22854">says</a>, </p>
<blockquote><p>I didn&#8217;t expect someone to walk into our homes and slap us in the face like this.</p></blockquote>
<p>There is a lot to respond to in this quote, which was probably made in anger, but it reveals a flash of what makes the community work. DHH, and the other principals of the community, have a sense of pride and ownership. They care about the community</p>
<p>If I can build that in only of a few of the factscollector communities, I will have been wildly successful.</p>
<hr />
<p>Update: Sept. 26th. Martin Fowler <a href="http://martinfowler.com/bliki/RubyPeople.html">points</a>  to the general friendliness of the Ruby community as a factor in its acceptance. I&#8217;d agree. In particular, I&#8217;d draw a comparison between Ruby and Perl. If someone asks a question to comp.lang.perl.misc that has either been asked before, is well documented, or just shows that the questioner hasn&#8217;t really done their homework, they will be shot down from five directions, added to killfiles, or ignored. The leading figures of the group will be doing this. </p>
<p>Ask the same kind of question in the Ruby on Rails group, people will fall over themselves to answer. If someone is a little rude, or terse, in their response, they&#8217;ll apologize.</p>
<p>This creates a culture of openness. People have the room to ask &#8220;dumb&#8221; questions, to question how things are done, and to propose new solutions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.warmroom.com/yesterdays/2005/09/22/another-good-thing-about-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test Based Specifications in Ruby on Rails</title>
		<link>http://www.warmroom.com/yesterdays/2005/09/21/test-based-specifications-in-ruby-on-rails/</link>
		<comments>http://www.warmroom.com/yesterdays/2005/09/21/test-based-specifications-in-ruby-on-rails/#comments</comments>
		<pubDate>Wed, 21 Sep 2005 16:25:23 +0000</pubDate>
		<dc:creator>Ray Baxter</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.warmroom.com/wordpress/?p=127</guid>
		<description><![CDATA[I am starting to experiment with writing unit and funtional tests for factscollector. I haven&#8217;t ever worked with consistent automated testing. I probably waited too long to start, both in general, and in this particular Ruby on Rails project. The general reasons are well known in the Agile Programing literature. Tthe existance of the test [...]]]></description>
			<content:encoded><![CDATA[<p>I am starting to experiment with writing unit and funtional tests for factscollector. I haven&#8217;t ever worked with consistent automated testing.</p>
<p>I probably waited too long to start, both in general, and in this particular Ruby on Rails project. The general reasons are well known in the Agile Programing literature. Tthe existance of the test is a safety net. Having the test I can feel free to change to code and I don&#8217;t have to worry that I have broken something elsewhere in the code. The tests document what the code does, not what it ought to do. It occurs to me that tests are better than comments in this sense. Also, automatic tests are like double entry bookkeeping. It is easy to make a mistake. It is much harder to make two mistakes that exactly cancel each other out.</p>
<p>On factscollector, I waited too long because I found a couple of bugs in Rails. One was a documentation bug in ActionMailer and the other was  in an interaction between controllers. Both  that took me a while to track down, particularly because I was more suspicious of my own code than of the framework. (Why is that? Whenever I learn a new language, or a new tool, I am more suspicious of myself than I am of this completely unknown tool? That&#8217;s not my default in most areas of life.) Both of these bugs would have been easier to track down if I had had functioning tests earlier, if only because the domain of the problem would have been radcally circumscribed.</p>
<p>While researching these issues, I came across <a title="Revieworld CTOâs blog ï¿½ A test by any other nameâ¦" href="http://www.reevoo.com/blogs/bengriffiths/2005/06/24/a-test-by-any-other-name/">this post</a> from Ben Griffiths, CTO of <a href="http://www.reevoo.com/">Reevoo</a>.</p>
<p>He advocates a template for creating and naming tests that serves as documentation for what the application actually does. Examples are worth many words, here is one of my tests:</p>
<p><code>
     def test_should_return_user_to_login_template_on_incorrect_password
       login "bob", "not_correct"
       assert_template_has "login"
     end
</code></p>
<p>The test is very short. It tests exactly one thing. The name says that thing. It says it in an obvious pattern and Ben offers up a Rake task that outputs these as a pass at documenting what the application does. Here is a segment of mine from my user controller.</p>
<p><code>
user_controller should:
 - allow creation of new user on valid password
 - send mail on successful user creation
 - not send mail on bad password
 - not send mail on bad email
 - display flash on successful login
 - not allow existing user to login on  incorrect password
 - return user to login on incorrect password
 - store logged in user in session
</code></p>
<p>These are discrete areas of functionality. All of these are very small. The collection of all of the tests (that pass, anyway) is a concrete expression of what the application can do right now.</p>
<p>This has been a huge productivity boon for me. As I&#8217;m visualizing what the application will do, I&#8217;m writing the test names. The names of the tests are the specification. This is actually fun, so I do  it and then the excitement drives me to fill in the test and since the tests fail, I have to write the code to make the tests pass. </p>
<p>Looking at the actions documented here, I think I could improve the specificity of these names and improve the clarity of my thinking and my design. Ben recommends the template &#8220;test_should_***_on_***&#8221;. If the all the tests are short and sweet, like my example, then the possibilities for creating a test that don&#8217;t test what they purport to test are minimal. If the tests fail, it is immediately obvious what the application isn&#8217;t doing correctly, without going into the code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.warmroom.com/yesterdays/2005/09/21/test-based-specifications-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby On Rails Experiments</title>
		<link>http://www.warmroom.com/yesterdays/2005/03/28/ruby-on-rails-experiments/</link>
		<comments>http://www.warmroom.com/yesterdays/2005/03/28/ruby-on-rails-experiments/#comments</comments>
		<pubDate>Mon, 28 Mar 2005 07:38:55 +0000</pubDate>
		<dc:creator>Ray Baxter</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software & Internet]]></category>

		<guid isPermaLink="false">http://www.warmroom.com/wordpress/?p=29</guid>
		<description><![CDATA[I have been playing around with Ruby and Ruby on Rails. Based on the examples that I see (like this one for instance, this looks like a lead pipe cinch for implementing a few similar projects of my own that have been hanging around for a while, namely my training log project, my GTD combined [...]]]></description>
			<content:encoded><![CDATA[<p>I have been playing around with Ruby and Ruby on Rails. Based on the examples that I see (like this <a href="http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html">one</a> for instance, this looks like a lead pipe cinch for implementing a few similar projects of my own that have been hanging around for a while, namely my training log project, my GTD combined project and to do list tracker, and my time tracker.  These projects are all fundamentally the same, there is is series of tasks, projected or completed, and including various associated data, to track, and some logic that governs managing the state transitions of these tasks and the planning and reporting of these tasks.</p>
<p>I followed through that tutorial and I thought I was pretty clued in to what was happening and why. So I jumped in to try it myself. Since the training log project has been kicking around in my mind the longest, I thought I would give that a go. In retrospect, this was probably a bad idea. I had done several fitful starts on this project and so I had an existing database schema and other architectural ideas, that maybe weren&#8217;t so easily adapted to an out-of-the-box Rails project. My second mistake was to install an update to Rails (0.11) between reading the tutorial and turning to my own work. This confused that analysis of the later problems no end.</p>
<p>The first gotcha that I encountered was that database schema. I had defined several Type tables that were used in other tables, there was a ActivityTypes table that listed all the different activity records that could appear in the Workouts table, a WorkoutTypes table that described the status of the workout (planned, library, or completed), etc. These tables may not ultimately be very useful in Rails, or maybe they will, but the problem is that I created these tables without following the ActiveRecord conventions &#8211; lower case, plural table names for objects, the primary key should be a sequence named id, and foreign keys should be named lowercaseforeigntable_id. Instead of wiping the slate clean, I went in and fixed these problems one at a time. The combination of these two, with the intervening update of Rails was a mess.</p>
<p>Once I started over with reasonable incremental development practices, I was sailing smoothly, except it appears that Rails (WEBrick server) doesn&#8217;t clean up from old sessions, and by old, I mean really old. I was getting NoMethodErrors on every page that I attempted. This didn&#8217;t make any sense, but Goggle handed me the answer <a href="http://www.carpeaqua.com/archives/2005/03/22/rails_0110_gotcha.php">here</a>. It seems like my earlier testing on the tutorial was sticking around and my new framework wasn&#8217;t being read.</p>
<p>The third obstacle was really very minor. In Curt Hibbs follow up to his Rolling on Rails, <a href="http://www.onlamp.com/pub/a/onlamp/2005/03/03/rails.html">Part 2</a> he alluded to using the Rails generator to create the entire scaffold of an application. He doesn&#8217;t make a detailed mention, but base on what he said, I assumed that the <code>scaffold :workout</code> line would automatically be added to my controllers/workout_controller.rb file. Not so.</p>
<p>Now after, a few hours of productive work, and another few unproductive hours, I have a working application. Everything else is just stepwise refinement.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.warmroom.com/yesterdays/2005/03/28/ruby-on-rails-experiments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

