<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3990494233472101395</id><updated>2011-08-23T19:46:58.226-07:00</updated><title type='text'>Bash My Nonsense</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bashmynonsense.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bashmynonsense.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>TiC</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://bp2.blogger.com/_WRSsUbAAWTw/R-gTQb_7GkI/AAAAAAAABXo/3mgk6W_S77I/S220/DSC_0063-1.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3990494233472101395.post-1588042305565265145</id><published>2010-10-07T10:33:00.000-07:00</published><updated>2010-10-07T10:37:54.732-07:00</updated><title type='text'>Fun with ssh</title><content type='html'>I was trying all morning to ssh into a server with the public key authentication. There's a page about &lt;a href="http://sial.org/howto/openssh/publickey-auth/problems/"&gt;troubleshooting the public key authentication&lt;/a&gt;. I suspected the server is so old it uses ssh 1.5, but no. I can't think of something else beside googling on the error message: &lt;br /&gt;&lt;br /&gt;Agent admitted failure to sign using the key.&lt;br /&gt;&lt;br /&gt;And there it is: &lt;a href="https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/201786"&gt;a bug on ubuntu&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3990494233472101395-1588042305565265145?l=bashmynonsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bashmynonsense.blogspot.com/feeds/1588042305565265145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3990494233472101395&amp;postID=1588042305565265145' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/1588042305565265145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/1588042305565265145'/><link rel='alternate' type='text/html' href='http://bashmynonsense.blogspot.com/2010/10/fun-with-ssh.html' title='Fun with ssh'/><author><name>TiC</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://bp2.blogger.com/_WRSsUbAAWTw/R-gTQb_7GkI/AAAAAAAABXo/3mgk6W_S77I/S220/DSC_0063-1.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3990494233472101395.post-2262239962385193769</id><published>2010-04-08T17:19:00.001-07:00</published><updated>2010-04-08T17:50:28.487-07:00</updated><title type='text'>Indentation, indentation...</title><content type='html'>So, lately I see many developers prefer what I call ASCII Art Indentation style such as:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Class Foo&lt;br /&gt;  def bar(params = {})&lt;br /&gt;    Barf.find(params.merge :key  =&gt; "value",&lt;br /&gt;                           :key2 =&gt; "value2", ... and so on )&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;with the claim that it reads better, and you know exactly where to look for things. &lt;br /&gt;&lt;br /&gt;I say it's completely opposite. It is no where near intuitive. &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Say you have to change params to parameter_name_that_makes_more_sense ? you have to adjust your &lt;strong&gt;whole&lt;/strong&gt; code base to reflect your tiny change, and apparently no one does.&lt;/li&gt;&lt;br /&gt;&lt;li&gt; For something like:&lt;br /&gt;&lt;div&gt;&lt;pre&gt;&lt;br /&gt;  Sundae.new(Icecream.with_fruit.no_sugar.all(:include =&gt; [:nutrition_facts, :production_plan]), :whipped_cream =&gt; WhippedCream.no_fat.first(:conditions =&gt; ["make is not :make and calorie &lt; :calorie", {:make =&gt; "Booga", :calorie =&gt; 120}])) &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;How do you systematically define the ASCII Art Indentation scheme that every one will follow and give exactly the same indentation? Where do you look for the make of the whipped cream? Not easy.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;And for some reason, people loath my style of indentation: 1 more soft tab when you open a paren, brace, or bracket followed by a new line. and new line and one fewer soft tab before the close of the matching paren, brace, or bracket. It is said it's hard to see where things are, and it increases the number of lines. But behold:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  Sundae.new(&lt;br /&gt;    Icecream.with_fruit.no_sugar.all(&lt;br /&gt;      :include =&gt; [:nutrition_facts, :production_plan] &lt;br /&gt;    ), &lt;br /&gt;    :whipped_cream =&gt; WhippedCream.no_fat.first(&lt;br /&gt;      :conditions =&gt; [&lt;br /&gt;        "make is not :make and calorie &lt; :calorie", &lt;br /&gt;        {:make =&gt; "Booga", :calorie =&gt; 120}&lt;br /&gt;      ]&lt;br /&gt;    )&lt;br /&gt;  )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;You can choose not to indent if your list is small enough, less than, say, 40 characters, half the 80x24 line.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can write your code easily to indent stuff for you, consistently.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can instruct people easily to indent the exact same way and give the exact same result.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You know exactly where you miss your close paren.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You know exactly where you can find your make of the whipped cream. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Your code rarely falls off the right edge while leaving an airstrip on the left side.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;&lt;br /&gt;Prove me wrong, someone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3990494233472101395-2262239962385193769?l=bashmynonsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bashmynonsense.blogspot.com/feeds/2262239962385193769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3990494233472101395&amp;postID=2262239962385193769' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/2262239962385193769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/2262239962385193769'/><link rel='alternate' type='text/html' href='http://bashmynonsense.blogspot.com/2010/04/indentation-indentation.html' title='Indentation, indentation...'/><author><name>TiC</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://bp2.blogger.com/_WRSsUbAAWTw/R-gTQb_7GkI/AAAAAAAABXo/3mgk6W_S77I/S220/DSC_0063-1.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3990494233472101395.post-6778996618234812277</id><published>2010-04-08T16:52:00.000-07:00</published><updated>2010-04-08T18:00:48.089-07:00</updated><title type='text'>.not is EVIL!</title><content type='html'>What's a .not? &lt;br /&gt;&lt;br /&gt;.not is a decorator method that decorates the object, so that the boolean method call that immediately follows the not call is negated. For example, if self.is_italic? returns true, self.not.is_italic? returns false. &lt;br /&gt;&lt;br /&gt;Why would people use .not? &lt;br /&gt;&lt;br /&gt;The only reason I have heard so far is because it sounds more like English...Pffft, sounds more like English! &lt;br /&gt;&lt;br /&gt;Person.find_by_name("Paul Frank").not.is_popular? &lt;br /&gt;&lt;br /&gt;How is that anyway similar to English: Is Paul Frank not popular? &lt;br /&gt;&lt;br /&gt;What's wrong with logical negation '!' ? The only reason I have heard so far is that it's at the head of the statement, and with long condition, it falls off the screen... Pffft, falls off the screen!&lt;br /&gt;&lt;br /&gt;First, I don't believe in reinventing the wheel that is worse than the original one.&lt;br /&gt;Second, instead of using a CPU to flip a bit, we malloc the heap, create an object, extend some other object with this object, which alias the method to use a CPU to flip the flipping bit! &lt;br /&gt;Oh, did I mention it's stupid?&lt;br /&gt;&lt;br /&gt;In addition to that, .not is broken. In any given object, you cannot call .not on the boolean variable. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Class Person&lt;br /&gt;  @humorous = false;&lt;br /&gt;&lt;br /&gt;  def foo&lt;br /&gt;    @humorous.not #=&gt; is not going to do anything!&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;More over, what prevents someone from doing foo = bar.not, and a thousand lines later, some other call foo.is_real? without knowing that it is being 'notted'?&lt;br /&gt;&lt;br /&gt;So you cannot get rid of ! anyway. The best you can do is use the not operator to avoid !, then you have precedence problem to think about. &lt;br /&gt;&lt;br /&gt;People then say oh who cares, how many CPU time do you use over that? I'd rather have more style than looking like C. &lt;br /&gt;&lt;br /&gt;Well, you see, you don't usually run around a building complex just to go from your desk to the break room 25 feet away, even though it doesn't affect one bit the history of mankind. You don't do that because it's stupid. Oh, and did I mention .not is stupid in exactly the same way?&lt;br /&gt;&lt;br /&gt;! has been around since the dawn of computer programming. Whoever thinks ! is not readable should quit programming and do some research on herbal hair gel. If your condition is way too long for you to see ! on a 24" 1080p widescreen, it's a code smell that you should rethink your logic, or model design in general. Whoever thinks ! is ugly and remind them of C should appreciate their own breadth of knowledge, and that without C there is no .not, and the fact that languages are means, not the goal. &lt;br /&gt;&lt;br /&gt;Remind yourselves to always do the simplest thing that makes sense. .not is not simple, and not making much of a sense either.&lt;br /&gt;\No new line at the end of file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3990494233472101395-6778996618234812277?l=bashmynonsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bashmynonsense.blogspot.com/feeds/6778996618234812277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3990494233472101395&amp;postID=6778996618234812277' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/6778996618234812277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/6778996618234812277'/><link rel='alternate' type='text/html' href='http://bashmynonsense.blogspot.com/2010/04/not-is-evil.html' title='.not is EVIL!'/><author><name>TiC</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://bp2.blogger.com/_WRSsUbAAWTw/R-gTQb_7GkI/AAAAAAAABXo/3mgk6W_S77I/S220/DSC_0063-1.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3990494233472101395.post-3100285078767053087</id><published>2009-01-22T12:01:00.001-08:00</published><updated>2009-01-22T12:15:34.022-08:00</updated><title type='text'>Uploading a file.... from browser to a webapp, to another webapp ???</title><content type='html'>It's been six and a half months since I last do anything interesting, but here it is.&lt;br /&gt;&lt;br /&gt;Problem: We have a RESTful web service, and a web application that talks to each other. We want to allow the user to upload a file, particularly binary, to the web app, and put that in the database in the REST server. &lt;br /&gt;- We can't make a multipart request from the app to the REST server, it will come out as a string literal "&lt;ActionController::UploadedStringIO&gt;".&lt;br /&gt;- We can't call read on the UploadedStringIO and put that into the request from the app to the REST server. It will come out as gibberish string. &lt;br /&gt;- We can't put the specific header that we want to do a multi-part request. I didn't even dare track that down.&lt;br /&gt;- I was going to try make a raw HTTP request, saving the file in a temporary file on the app somewhere, but before I did that, I realized something...&lt;br /&gt;&lt;br /&gt;IT'S ALL XML!&lt;br /&gt;&lt;br /&gt;When we make requests to REST server using ActiveResource, the request body is marshaled into xml format. That means all your binary is going to mess up the xml document, and/or recognized as the string literal above. &lt;br /&gt;&lt;br /&gt;What do I do?&lt;br /&gt;&lt;br /&gt;A multi-part stream has a few important attributes: original_filename, content_type, and the file data we can get by calling read on the IO object. So I created a hash with these attribute names as keys (call the content whatever you like, make sure your REST server knows what it is and fetch it accordingly), and the value from the user's request as the value. I encode the binary content with the Base64.encode64. Now this hash can be marshaled easily. It's all ASCII text. So, go ahead and put that in your request parameters and fire away.&lt;br /&gt;&lt;br /&gt;On the server side, handle the request as you would normally, except when you write the file to your storage, remind yourself that it is encoded by Base64. &lt;br /&gt;&lt;br /&gt;Now comes the other way around, showing what we just uploaded. Again, it's all xml up until it reaches the app. So, fetch what you stored, make sure it goes out the REST server with the binary content encoded with Base64, and decode it at the app when you're ready to present it on screen. &lt;br /&gt;&lt;br /&gt;This works pretty well with ActiveResource. A nice feature request to ActiveResource people would be to automate all this. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3990494233472101395-3100285078767053087?l=bashmynonsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bashmynonsense.blogspot.com/feeds/3100285078767053087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3990494233472101395&amp;postID=3100285078767053087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/3100285078767053087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/3100285078767053087'/><link rel='alternate' type='text/html' href='http://bashmynonsense.blogspot.com/2009/01/uploading-file-from-browser-to-webapp.html' title='Uploading a file.... from browser to a webapp, to another webapp ???'/><author><name>TiC</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://bp2.blogger.com/_WRSsUbAAWTw/R-gTQb_7GkI/AAAAAAAABXo/3mgk6W_S77I/S220/DSC_0063-1.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3990494233472101395.post-6196379403087350675</id><published>2008-06-03T12:23:00.000-07:00</published><updated>2008-06-03T13:43:44.976-07:00</updated><title type='text'>Asymmetrical database structures between production and non-production environments</title><content type='html'>So long time ago, before I was born as a consultant, there was some specific needs for the database tables. What we need was a table to mock external databases that we don't have access to in the development environment but the production does. What we did was creating a table right in the test cases and deal with it there. &lt;br /&gt;&lt;br /&gt;Problems followed. &lt;br /&gt;&lt;br /&gt;For one, MySQL and Rails doesn't have support for nested transaction. &lt;br /&gt;For two, All tests written are in transaction that is rolled back every time the method ends. &lt;br /&gt;For three, we need to ensure that the implementation employs the transaction mechanism somehow. &lt;br /&gt;&lt;br /&gt;Whenever we create a new table, the transaction stops working. Whatever we did to the database, it was showing in the later test methods. Therefore there is no way we can ensure that when the transaction was supposed to be rolled back, it was indeed rolled back.&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;br /&gt;The best we could do at that time was clearing out the tables ourselves. Andy Kotlinski wrote an assertion called assert_in_transaction to work around the problem. Talk to him if you would like more information on it. &lt;br /&gt;&lt;br /&gt;Several months passed. The project was shelved for whatever reason. &lt;br /&gt;Yet other months passed. The client decided to dig the zombie out of the grave. &lt;br /&gt;&lt;br /&gt;All hell broke lose. &lt;br /&gt;&lt;br /&gt;Somehow, Rails 2.0 doesn't allow us to work around it the way we did any more. The reason was something I couldn't remember any more because I forgot to blog about it at the time of digging that grave. What do we do? &lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;br /&gt;Instead of creating the tables in the test methods, I thought of a different way. &lt;br /&gt;&lt;br /&gt;I want to have the transaction working.&lt;br /&gt;I hate putting Data Description Language into the tests. &lt;br /&gt;I like the "Elegance: Simple and Powerful", quoting Dr. David Matuszek from the University of Pennsylvania.&lt;br /&gt;&lt;br /&gt;It turns out that we completely overlooked the power of Ruby. Database migrations are Ruby files. It means we can do pretty much anything a Ruby file can do. So we employ a simple condition to the migration&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if RAILS_ENV == 'test' &lt;br /&gt;  create_your_fancy_test_tables&lt;br /&gt;else&lt;br /&gt;  do_some_funny_stuff&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not bad, but still, not good. Why? Because we also want it in the development database too. And what happens when you have 8 different environments and you have to hand pick them?&lt;br /&gt;&lt;br /&gt;Take two:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;unless ['production'].include? RAILS_ENV do&lt;br /&gt;  create_your_fancy_test_tables&lt;br /&gt;else&lt;br /&gt;  do_some_funny_stuff&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Better. But still, what happens when you have 20 different migrations ahead?&lt;br /&gt;&lt;br /&gt;Take three:&lt;br /&gt;&lt;br /&gt;Define a module like so:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;module SkipEnv&lt;br /&gt;  def skip_env&lt;br /&gt;    unless ['production'].include? RAILS_ENV do&lt;br /&gt;      yield&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Put the module in the lib directory. Then, in the migration:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class &lt;&lt; self do; include SkipEnv; end&lt;br /&gt;&lt;br /&gt;def self.up&lt;br /&gt;  skip_env do&lt;br /&gt;    create_your_fancy_test_tables&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def self.down&lt;br /&gt;  skip_env do&lt;br /&gt;    drop_your_fancy_test_tables&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hmm.. something's missing: the do_your_fancy_stuff. It turns out, our do_your_fancy_stuff does absolutely nothing, so we just cut it out.&lt;br /&gt;&lt;br /&gt;It has to be a class method because the migration up and down methods are class methods. &lt;br /&gt;&lt;br /&gt;Alright, looks good. We can create test tables anywhere except production, or any other environments you put into the array, and we can choose to skip environments in anything having access to the lib folder of the rails app, not only migrations. Awesome. &lt;br /&gt;&lt;br /&gt;Further refinement would be to put it as a plugin, and install it in any Rails app you happen to have the need for such mechanism. &lt;br /&gt;&lt;br /&gt;We didn't do that, because the zombie was buried back in the ground... again. This time, the reason is that to fix it and make it works for Rails 2 and have ActiveResource support, we would need to take a month and work on it full time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3990494233472101395-6196379403087350675?l=bashmynonsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bashmynonsense.blogspot.com/feeds/6196379403087350675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3990494233472101395&amp;postID=6196379403087350675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/6196379403087350675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/6196379403087350675'/><link rel='alternate' type='text/html' href='http://bashmynonsense.blogspot.com/2008/06/asymmetrical-database-structures.html' title='Asymmetrical database structures between production and non-production environments'/><author><name>TiC</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://bp2.blogger.com/_WRSsUbAAWTw/R-gTQb_7GkI/AAAAAAAABXo/3mgk6W_S77I/S220/DSC_0063-1.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3990494233472101395.post-826895353153990970</id><published>2008-05-08T12:43:00.000-07:00</published><updated>2008-05-08T13:04:58.981-07:00</updated><title type='text'>Pagination with ActiveResource</title><content type='html'>Ok, so we have a RESTful web service written in Ruby on Rails which has thousands of records to display. Viewing them all at once times out the client badly. What do we do? Pagination comes into the rescue, of course.&lt;br /&gt;&lt;br /&gt;How do we accomplish that? &lt;br /&gt;&lt;br /&gt;First try:&lt;br /&gt;We added will_paginate to both the REST server and the Rails client. We render using the erb to include the total_entries and per_page attributes required by the will_paginate in the client side. &lt;br /&gt;&lt;br /&gt;Problems arise with this. Hash conversions extension of Rails only expects that an array type node has only one kind of child, and it's the list of what it represents. However, we put the two attributes into the returned array too. What happened? Since XML is parsed out as a hash in the first place, and hash is unordered. The conversions extensions will pick any value from the hash whose key is not 'type'. So, sometimes it gets the correct things, other times, it doesn't. The only error message it sends out is "can't typecast #{entries}" where entries is mistakenly the value of either our total_entries or per_page. &lt;br /&gt;&lt;br /&gt;It worked in ALL of our entities we paginated, except the last one. With the same code, doing only one different thing in one different cases, I pulled 75 hairs out of my ugly beard. What could possibly go wrong? Is it the REST server? Is it the find? NO! They behave in other entities, except this one. ... ok... stack trace.. ok, meta programming, we can't go any further... oh my god... it's the conversions!!! &lt;br /&gt;&lt;br /&gt;To plow ahead and go forward with this approach, we can change the conversions.rb to detect anything NOT 'type', 'per_page', or 'total_entries'. BUT my pair over here is very strongly against changing rails. So came his idea ... &lt;br /&gt;&lt;br /&gt;Take 2: &lt;br /&gt;Apparently it's quite hard to have an array with a custom instance method. So, we don't do it. On the REST side, we don't include will_paginate at all. On the client side, we call the REST like so:&lt;br /&gt;&lt;br /&gt;Model.find(:all, :params =&gt; {:limit =&gt; blah, :offset =&gt; blah})&lt;br /&gt;&lt;br /&gt;blah's are calculated according to which page it is and how many per page we want. &lt;br /&gt;&lt;br /&gt;On the REST side, we have to process the params a little bit. The params are sent in with strings as keys, all we need to do is change them all to symbols. &lt;br /&gt;&lt;br /&gt;Model.find(:all, {:limit =&gt; params[:limit], :offset =&gt; params[:offset]})&lt;br /&gt;&lt;br /&gt;As you can see here, you can access the params using the symbol as the key, but it is actually stored as strings, and the error you see is:&lt;br /&gt;&lt;br /&gt;can't recognize key limit, offset&lt;br /&gt;&lt;br /&gt;Not very obvious, and I lost 20 hair of my beard figuring this out. &lt;br /&gt;Also, you need an extra action on the REST side to tell how many record it has. Call that from the client and keep it as a param for the WillPaginate::Collection creation&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This way, we get only what we need from the REST, the big half purpose of pagination. (The lesser half is the usability.) Now, we construct the WillPaginate::Collection like so: &lt;br /&gt;&lt;br /&gt;@entities = WillPaginate::Collection.create(page, per_page, count, returned_array)&lt;br /&gt;&lt;br /&gt;Finally, in the view, you paginate the @entities as you would a paginate collection you got from the ActiveRecord counterpart.&lt;br /&gt;&lt;br /&gt;Thanks Arnold for coming up with this idea for me to blog and brag about solving this. LOL&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3990494233472101395-826895353153990970?l=bashmynonsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bashmynonsense.blogspot.com/feeds/826895353153990970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3990494233472101395&amp;postID=826895353153990970' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/826895353153990970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3990494233472101395/posts/default/826895353153990970'/><link rel='alternate' type='text/html' href='http://bashmynonsense.blogspot.com/2008/05/pagination-with-activeresource.html' title='Pagination with ActiveResource'/><author><name>TiC</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='21' src='http://bp2.blogger.com/_WRSsUbAAWTw/R-gTQb_7GkI/AAAAAAAABXo/3mgk6W_S77I/S220/DSC_0063-1.JPG'/></author><thr:total>3</thr:total></entry></feed>
