<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Moves On Rails: Category Ruby</title>
    <link>http://www.movesonrails.com/articles/category/ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>New ways to look at software</description>
    <item>
      <title>Rails log analyzer</title>
      <description>&lt;p&gt;You've probably all been there: your application is running slow, but why? What views or actions are clogging up the mongrels? Or are the mongrels just waiting for the database?&lt;/p&gt;

&lt;p&gt;Rails log analyzer is a simple but very powerful command-line analysis tool to quickly determine what is taking time, on all kinds of different levels. At the moment it can tell you the following statistics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Top 10 most requested actions&lt;/li&gt;
&lt;li&gt;Top 10 actions by time - cumulative&lt;/li&gt;
&lt;li&gt;Top 10 actions by time - per request mean&lt;/li&gt;
&lt;li&gt;Top 10 worst DB offenders - cumulative time&lt;/li&gt;
&lt;li&gt;Top 10 worst DB offenders - mean time&lt;/li&gt;
&lt;li&gt;Mongrel process blockers (&gt; 1.0 seconds) - frequency&lt;/li&gt;
&lt;li&gt;Requests graph - requests per hour&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an example run, or the analyzer take a look at the github.
&lt;a href="http://github.com/wvanbergen/rails-log-analyzer/"&gt;http://github.com/wvanbergen/rails-log-analyzer/&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 14 Aug 2008 22:58:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:af66f557-bf78-4b31-b5aa-60618aaf455e</guid>
      <author>bart.tenbrinke@movesonrails.com (Bart ten Brinke)</author>
      <link>http://www.movesonrails.com/articles/2008/08/14/rails-log-analyzer</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>log</category>
      <category>analyzer</category>
      <category>command</category>
      <category>line</category>
    </item>
    <item>
      <title>Optimizing math</title>
      <description>&lt;p&gt;As you might have guessed from Bart's previous article we've been looking at ways to speed up our Rails app. We've been profiling and query optimizing but at some point we reached a dead end.&lt;/p&gt;

&lt;p&gt;Our app needs to calculate a lot of distances between geo locations. Until now we've been happy using a home-grown Ruby method to calculate these distances but our profiling showed that it was (as one may suspect) horribly slow.&lt;/p&gt;

&lt;p&gt;We now have several options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We could try to built a faster Ruby method (but that would be hard since it's pure math and not really a lot can be done here)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We could use the database (mysql in our case) to calculate our distances (A lot more db connections in our case, since we need distances between lots of points. Not the standard stuff that gems like acts_as_mappable can handle)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use RubyInline to create a faster C based method&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We decided to look at RubyInline. A gem that enabled C code to be used right inside a Ruby script. We rewrote the method in C. A simple benchmark proved that our inline C method was 2.3 times faster!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;pre&gt;
require 'inline'
inline do |builder|
    builder.include '&amp;lt;math.h&amp;gt;'
    builder.c "double calc_distance_between(...) { ... }"
end
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Although this result is very good, it does complicate your app and makes it less readable. These inline methods have to be used with care. But in our simple (and very localized) case we decided to keep the C method in favor of the pure Ruby call.&lt;/p&gt;</description>
      <pubDate>Thu, 10 Apr 2008 22:43:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:341a43a2-ff84-429a-b541-ca10ccb44f5d</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2008/04/10/optimizing-math</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>rubyinline</category>
      <category>C</category>
      <category>math</category>
      <category>profile</category>
      <category>speed</category>
      <category>distance</category>
    </item>
    <item>
      <title>attr_accessor_with_default</title>
      <description>&lt;p&gt;What a marvelous feature, but be wary! It can cause some unexpected behavior if you don't know what you are doing.&lt;/p&gt;

&lt;p&gt;This morning we found a rather suspicious bug that lead to unexpected things. Here is an example:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;
    class Person ; attr_accessor_with_default :things, {} ; end&lt;br/&gt;
    john = Person.new&lt;br/&gt;
    john.things[:table] = true&lt;br/&gt;
    ...&lt;br/&gt;
    jim = Person.new&lt;br/&gt;
    jim.things =&gt; {:table =&gt; true} # huh??&lt;br/&gt;
    &lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As it would seem attr_accessor_with_default has some problems with collections. Since we are sharing the instance over the entire class. Peter Williams noted this problem several month ago in his &lt;a href="http://pezra.barelyenough.org/blog/2007/09/things-to-be-suspicious-of-attr_accessor_with_default-with-a-collection/"&gt;article&lt;/a&gt; (which we didn't read until it was too late), however the solution he provided still left us with some very undesireable behaviour.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;
    class Person ; attr_accessor_with_default :things, {{}} ; end # note the extra brackets!&lt;br/&gt;
    &lt;br/&gt;&lt;br/&gt;
    john = Person.new&lt;br/&gt;
    john.things[:table] = true&lt;br/&gt;
    &lt;br/&gt;
    ...&lt;br/&gt;
    &lt;br/&gt;
    jim = Person.new&lt;br/&gt;
    jim.things =&gt; {} # okay!&lt;br/&gt;
    john.things =&gt; {} # uhm... not okay!
    &lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The variable would only &lt;em&gt;stick&lt;/em&gt; if we actually assigned it.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;
    john.things = {:table =&gt; true}&lt;br/&gt;
    john.things =&gt; {:table =&gt; true} # yay!
    &lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But doing this every time is not only a pain but also introduces &lt;strong&gt;very&lt;/strong&gt; hard to debug errors, since the assignment does not fail...it just doesn't work!&lt;/p&gt;

&lt;p&gt;We solved it by going old-school. Back to the normal accessor for collections.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;
    class Person &lt;br/&gt;
       attr_accessor :things&lt;br/&gt;
     &lt;br/&gt;
       &amp;nbsp;def initialize attributes=nil&lt;br/&gt;
       &amp;nbsp;&amp;nbsp;super&lt;br/&gt;
       &amp;nbsp;&amp;nbsp;self.things = {}&lt;br/&gt;
       &amp;nbsp;end&lt;br/&gt;
    &lt;br/&gt;
    end
    &lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now the code works as expected and we can use all operators (like &gt;&gt;, []) from the get go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; It seems this had no effect on ActiveRecord objects that were created using finders so here is the fix for any those:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;
    class Person &amp;lt; ActiveRecord::Base&lt;br/&gt;
       attr_accessor :things&lt;br/&gt;
     &lt;br/&gt;
       &amp;nbsp;def after_initialize&lt;br/&gt;
       &amp;nbsp;&amp;nbsp;self.things = {}&lt;br/&gt;
       &amp;nbsp;end&lt;br/&gt;
    &lt;br/&gt;
    end
    &lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <pubDate>Wed, 05 Mar 2008 09:37:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:830e2280-fc19-42e0-a443-5cd1b6eb4377</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2008/03/05/attr_accessor_with_default</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>attr_accessor_with_default</category>
      <category>collection</category>
      <category>weird</category>
    </item>
    <item>
      <title>Javascript testing problems</title>
      <description>&lt;p&gt;A few months ago I got the assignment to set up and build javascripts-tests for the scheduling view of moves. At first I had to select a testing-framework where the test would be written in. The framework had to be able to run both unit and integrations tests. Also it would be very nice if we can run these test automatically through the command-line instead of clicking around in the browser (autotest).&lt;/p&gt;

&lt;p&gt;After reviewing some frameworks, I chose the Crosscheck framework (http://www.thefrontside.net/crosscheck). Crosscheck is a javascript-testing-framework written in java. It is crossplatform and you can control it from the command-line. It is even able to emulate the behavior of multiple popular browsers like ie6, Firefox 1.0 and Firefox 1.5. Sounds like the ultimate testing framework!&lt;/p&gt;

&lt;p&gt;So after my decision I started playing around and implementing tests. However, when the tests became more complex I ran into trouble. Some basic browser features like document.write() (ie6) and the Option object where missing. I was able to work around these problems,  but the real trouble began with the integration tests. As our application relies heavily on ajax through the prototype framework, testing this functionality is crucial. However, I was not able to do this. Performing one hack after another, I finally gave up.&lt;/p&gt;

&lt;p&gt;The crosscheck framework was clearly not mature enough to satisfy my needs. My conclusion is: Using crosscheck for unit-testing is doable, but the framework is not mature enough for the use of integration tests. So what are the problems with crosscheck? As mentioned earlier, it is written in Java, so it tries to emulate the browser behavior based on it's specifications. The advantages of this approach is that you can emulate more than one browser, the disadvantages are that the emulation is an approach, so you will never really get the real behavior of the browser.&lt;/p&gt;

&lt;p&gt;If a browser changes its implementation, the framework is always outdated. You don't get the browsers quirks, so if it your tests pass in the test framework, there is no guarantee it will work in the real-browser world. Another problem with crosscheck is that is seems to be abandoned. The last changes are from end-2007 and as far as I can see none of the reported bugs have been fixed yet. Firefox 3.x and ie7 are becoming standard, but these browsers are not available as a test-browser in crosscheck (and there are no clues they will be soon).&lt;/p&gt;

&lt;p&gt;What can we expect from the continuity of crosscheck? If you, like us, want to be able to test a long-term project, then it is important that your test-framework is long-term too. So what does my ideal javascript-test-framework look like?&lt;/p&gt;

&lt;p&gt;It should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run from the command line&lt;/li&gt;
&lt;li&gt;Represent the browser realistically&lt;/li&gt;
&lt;li&gt;Emulate ajax responses&lt;/li&gt;
&lt;li&gt;Mock objects&lt;/li&gt;
&lt;li&gt;Run implementation tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As far as I know, no such framework exists. However, in my view, it shouldn't be too hard to realize. We could embed the mozilla tree in an application. That way we always have the latest version of the mozilla engine and an exact copy of the behavior including it's quirks. Through the Mozilla API we can access the DOM and other functions. The framework should be able to easily load tests and run them (for this part it's important to take a good look at the x-unit patterns).&lt;/p&gt;

&lt;p&gt;At this moment I don't have a clue how easy it is to emulate the ajax responses through mozilla API calls. Furthermore the framework should be give a rich toolkit for testing including abilities to mock objects. You start the framework via the command-line for easy integration with test-runners like autotest. Of course this application should be released under the GPL-licence. Now we only need someone to implement this for us!&lt;/p&gt;

&lt;p&gt;Steven van der Vegt (s.vandervegt TA student.utwente.nl)&lt;/p&gt;

&lt;p&gt;Ps we are offering an internship for the development of the described plugin at Nedap healthcare. Interrested? bart.tenbrinke@movesonrails.com International students welcome!&lt;/p&gt;</description>
      <pubDate>Tue, 04 Mar 2008 17:02:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:d683e0b3-e11a-4c99-a754-a7cef2863ffc</guid>
      <author>Steven van der Vegt</author>
      <link>http://www.movesonrails.com/articles/2008/03/04/javascript-testing-problems</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>Rspec</category>
      <category>autotest</category>
      <category>crosscheck</category>
      <category>javascript</category>
      <category>problems</category>
    </item>
    <item>
      <title>Autotest 100% CPU solution</title>
      <description>&lt;p&gt;Autotest is great, but when it is waiting for test, my MacBook turns into a whirlwind as autotest takes 100% CPU. After looking at autotest.rb, we easily find the waiting function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def wait_for_changes
  hook :waiting
  Kernel.sleep self.sleep until find_files_to_test
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As self.sleep is defaulted to 1 it means that my laptop does not sleep at all. Changing this is quite easy, as you can just add this to your .autotest file in your home directory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Autotest.add_hook :initialize do |at|
  at.sleep = 5
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Experiment with the amount to determine what  works for you. Offcourse autotest will now react slower to you changes, but hey: you can't have everything. Enjoy the silence!&lt;/p&gt;</description>
      <pubDate>Wed, 06 Feb 2008 09:42:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:66b85026-b2bb-4003-8906-21d0cb54b7cf</guid>
      <author>bart.tenbrinke@movesonrails.com (Bart ten Brinke)</author>
      <link>http://www.movesonrails.com/articles/2008/02/06/autotest-100-cpu-solution</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>Rspec</category>
      <category>autotest</category>
      <category>Rspec</category>
      <category>100</category>
      <category>Cpu</category>
    </item>
    <item>
      <title>The new programmers excuse for slacking of</title>
      <description>&lt;p&gt;&lt;center&gt;&lt;img src="http://www.movesonrails.com/files/compiling_new_style.png" alt=""/&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;Original by &lt;a href="http://xkcd.com/"&gt;XKCD&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Thu, 31 Jan 2008 14:39:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:a5b5b732-895c-4858-a342-b8f507341afc</guid>
      <author>bart.tenbrinke@movesonrails.com (Bart ten Brinke)</author>
      <link>http://www.movesonrails.com/articles/2008/01/31/the-new-programmers-excuse-for-slacking-of</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>Rspec</category>
      <category>Rspec</category>
      <category>compiling</category>
      <enclosure type="image/png" length="144103" url="http://www.movesonrails.com/files/compiling_new_style.png"/>
    </item>
    <item>
      <title>Cha-Ching and dutch banks</title>
      <description>&lt;p&gt;Like lots of you I bought the incredible MacHeist app bundle last week. One of the appz was Cha-Ching, a finance program to keep track of your money.&lt;/p&gt;

&lt;p&gt;One of the most useful features is the import. You can simply import all of your bank's records and be done with it. Unfortunately the dutch banks (or at least the Rabobank and Postbank) don't support the same formats Cha-Ching supports (like OFX/QIF).&lt;/p&gt;

&lt;p&gt;I wrote a small ruby script to convert the banks CSV files to OFX files. There are two separate files below (one for each bank):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.movesonrails.com/files/csv_convert.rb"&gt;CSV convertor - Postbank (Ruby)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.movesonrails.com/files/csv_rabo_convert.rb"&gt;CSV convertor - Rabobank (Ruby)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before you can run the files you need two additional gems (if you haven't got them already).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install extensions
sudo gem install builder
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After this you can use the scripts like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby csv_convert.rb [CSV FILE] &amp;gt; export.ofx
ruby csv_rabo_convert.rb [CSV FILE] &amp;gt; export.ofx
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Update: Now supports Tiger using PHP version of script and (optional) automator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the next files you don't need anything else than a vanilla Tiger install of OSX.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.movesonrails.com/files/csv_convert.php"&gt;CSV convertor - Postbank (PHP)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.movesonrails.com/files/csv_rabo_convert.php"&gt;CSV convertor - Rabobank (PHP)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use them like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;php csv_convert.php [CSV FILE] &amp;gt; export.ofx
php csv_rabo_convert.php [CSV FILE] &amp;gt; export.ofx
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For the simple version, use the automator zip file! Read the README to get it to work.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.movesonrails.com/files/csv_convert.zip"&gt;CSV convertor - Postbank/Rabobank (PHP/Automator)&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 23 Jan 2008 20:22:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:e46739f4-25d9-4e39-8ae9-223de2b0e88b</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2008/01/23/cha-ching-and-dutch-banks</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>cha</category>
      <category>ching</category>
      <category>rabobank</category>
      <category>postbank</category>
      <category>csv</category>
      <category>ofx</category>
    </item>
    <item>
      <title>Rspec plain text stories</title>
      <description>&lt;p&gt;Simply said. They are great. We've been using them since they came out and have been following the trunk ever since.&lt;/p&gt;

&lt;p&gt;They are so easy and elegant, they just needed a little TextMate love. So here you go: A language grammer and an adapted Vibrant Ink theme. (&lt;a href="http://www.movesonrails.com/files/Rspec_story_syntax.zip"&gt;Download here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src="http://www.movesonrails.com/files/Picture_2.png" alt=""/&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;P.S If anyone can tell me how to include stories in autotest runs I would be very happy!&lt;/p&gt;</description>
      <pubDate>Tue, 06 Nov 2007 15:50:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:d728e7e0-4cac-456f-b1ca-9058a318972b</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2007/11/06/rspec-plain-text-stories</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>Rspec</category>
      <category>textmate</category>
      <category>Rspec</category>
      <category>Stories</category>
      <category>Plaintext</category>
    </item>
    <item>
      <title>Moving to 2.0</title>
      <description>&lt;p&gt;Issues found so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Lots of small routing changes. Thank god for grep! : &lt;code&gt;addresses_path(@employee) =&gt; employee_addresses_path(@employee) &lt;/code&gt;. (Don't forget the *_url methods!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Several plugins failed due to &lt;code&gt;extract_options_from_args!&lt;/code&gt;. This method has been replaced with the nicer: &lt;code&gt;args.extract_options!&lt;/code&gt; (i.e acts_as_paranoid, acts_as_mappable, paginating_find)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;acts_as_paranoid had minor issues: fix by replacing &lt;code&gt;construct_count_with_legacy_args&lt;/code&gt; to &lt;code&gt;construct_count_options_from_args&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ActiveResource is now part of rails core. Be sure to freeze edge twice if you are upgrading from 1.2.3 or lower. All of our libXML additions had to be redone. (this time through /patches, tnx fngtps)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Different behavior of the render method. Before you could call &lt;code&gt;render "addresses/show"&lt;/code&gt; if you wanted to, this has been changed to &lt;code&gt;render :template =&gt; "addresses/show"&lt;/code&gt;. This affects several plugins too (like rspec_on_rails)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We no longer need the mysql_tasks plugin, since this functionality is now build right in!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;redhillonrails_core has some issues with connection adapters. Apparently rails 2.0 no longer loads adapters it doesn't need. This creates some issues with the redhills plugin since it tries to include stuff in those adapters. Adding a begin/rescue block around each include solves the issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The development environment no longer needs the &lt;code&gt;config.breakpoint_server = true&lt;/code&gt; setting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Polymorphic models are now saved with the base class as type in external objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Autocomplete textfields are now a plugin: &lt;code&gt;./script/plugin install auto_complete&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you have overridden the to_json methods, be sure to change that to &lt;code&gt;to_json options={}&lt;/code&gt;, else they might fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrations no longer working? Try removing duplicate names. We have two migrations with the same name (but different id) and it just skipped the first one (!)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speed! We did expect some speed increase, but this is major! Our pdf generating stuff uses a lot of ActiveRecord and we saw decreases of more than 50% request time.&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Thu, 18 Oct 2007 15:15:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:7d0e8dbf-83dc-4153-964a-88e93356d528</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2007/10/18/moving-to-2-0</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>update</category>
      <category>2.0</category>
      <category>edge</category>
      <category>rails</category>
      <category>problems</category>
    </item>
    <item>
      <title>ActiveResource: REST, WSDL, XSD?</title>
      <description>&lt;p&gt;We love REST. It's simple and clean, and combined with ActiveResource it is certainly the best app to app bridge we've worked with so far. But...&lt;/p&gt;

&lt;p&gt;What if you want to have more freedom? Say we want to build a database based on a REST webservice. Now imagine we don't want any info about the service in the ruby program that actually builds the db.&lt;/p&gt;

&lt;p&gt;We are facing two major problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We don't know which resources are available.&lt;/li&gt;
&lt;li&gt;We don't know the fields and types of the resource in advance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first problem will eventually be solved with WSDL 2.0 or if you need a solution right now: by a default listing resource. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;pre&gt;
 # Our default object is called a Resource, on the server we have 
 # a Resource object that just returns each resource we have in 
 # a string array.
&lt;/pre&gt;&lt;/code&gt;
&lt;code&gt;&lt;pre&gt;
 resources = Resource.find(:all)
   =&gt; ["address","person","country"]
&lt;/pre&gt;&lt;/code&gt;
&lt;code&gt;&lt;pre&gt;
 # Now we can do all kinds of crazy stuff :)
 resources.each do |resource|
   name = resource.capitalize.to_sym
   new_resource = Object.const_set(name, Class.new(ActiveResource::Base))
   new_resource.site = Resource.site
 end
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After this little piece of code we have a full dynamic set of ActiveResource classes ready to be used :)&lt;/p&gt;

&lt;p&gt;The second problem we face is much more interesting. Normally some kind of resource definition would be applied like XSD. But native ruby XSD support is kind of lacking (it sucks) and more importantly it doesn't feel like a rails solution.&lt;/p&gt;

&lt;p&gt;We wanted a cleaner, simpler and more elegant (more RESTy) solution. How about &lt;code&gt;Person.schema&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;It returns an ActiveResourceSchema object:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;pre&gt;
Person.schema.fields
   =&gt; { :name =&gt; FixNum, :date_of_birth =&gt; DateTime, 
:parents =&gt; [{ :id =&gt; FixNum }] }
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What happens is actually quite simple. When the Resource objects receives the schema method call it calls find(:first,  :params =&gt; { :schema =&gt; true }).&lt;/p&gt;

&lt;p&gt;The server responds to this param with a sample record, with just the field names and types. We build an ActiveResourceSchema object to wrap those and return a nice array of fields :)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; These code snippets are just examples, we are currently building this. If there's enough interest we might submit it as a plugin/patch for ARes.&lt;/p&gt;</description>
      <pubDate>Mon, 24 Sep 2007 15:57:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:5ff4b915-4fc7-4012-b445-707df57b1a1d</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2007/09/24/rest-wsdl-xsd</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>ActiveResource</category>
      <category>wdsl</category>
      <category>xsd</category>
      <category>REST</category>
      <category>XML</category>
    </item>
  </channel>
</rss>
