<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>RSS: Subscribe

Feeds:TwitterShared ItemsBookmarks

Links:ResumeWorkGitHub

Archive</description><title>JulioCapote</title><generator>Tumblr (3.0; @jcapote)</generator><link>http://jcapote.tumblr.com/</link><item><title>MigrationFor: Write migrations right from the command line!</title><description>&lt;p&gt;As someone who mostly stays in the rails console, I&amp;#8217;ve always hated forgetting a field, creating a migration, finding it among your other 500 migration files, then adding the one line you need to add, then running it. This is probably the most annoying part of the Rails experience. I&amp;#8217;ve always wanted to write a better migration generator that could take a list of commands/fields and write the migration for you, since most of the time what you name a migration has all the info it needs (add_index_to_post_id). Thanks to the heavily refactored plugin/generator API in Rails 3, I was able to do just that.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s take a look at how it works:&lt;/p&gt;

&lt;p&gt;First, install it (only works for Rails 3)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rails plugin install git://github.com/capotej/migration_for.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, you can create migrations like so:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rails g migration_for add_index:posts:posts_id&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It would generate db/migrate/20110103182654_add_index_posts_posts_id.rb):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class AddIndexPostsPostsId &amp;lt; ActiveRecord::Migration

   def self.up

      add_index 'posts','posts_id'

   end

   def self.down
     #waiting for reversible migrations in rails 3.1!
   end

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which you can then run normally with &lt;code&gt;rake db:migrate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s look at a more complex example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rails g migration_for create_table:posts add_column:posts:title:string 
add_column:posts:user_id:integer add_index:posts:user_id&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Would generate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; class CreateTablePostsaddColumnPostsTitleStringaddColumnPostsUserIdIntegeraddIndexPostsUserId &amp;lt; ActiveRecord::Migration

   def self.up

      create_table 'posts'

      add_column 'posts','title','string'

      add_column 'posts','user_id','integer'

      add_index 'posts','user_id'

   end

   def self.down
     #waiting for reversible migrations in rails 3.1!
   end

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It uses a lookup table with all the &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Migration.html"&gt;activerecord transformations&lt;/a&gt; and will only insert an expression into a migration if the method name is valid and it has the right number of arguments, so botched commands wont mess up the migration. Hope you enjoy it as much as I have!&lt;/p&gt;

&lt;p&gt;Source available here: &lt;a href="https://github.com/capotej/migration_for"&gt;https://github.com/capotej/migration_for&lt;/a&gt;&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/2583891119</link><guid>http://jcapote.tumblr.com/post/2583891119</guid><pubDate>Mon, 03 Jan 2011 13:48:00 -0500</pubDate></item><item><title>What I released in 2010</title><description>&lt;p&gt;Here&amp;#8217;s a recap of what I&amp;#8217;ve worked on and released in 2010:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Youtube Fraiche:&lt;/strong&gt;
I couldn&amp;#8217;t find a youtube downloader that worked on github, so I wrote my own one evening
&lt;a href="https://github.com/capotej/youtube_fraiche"&gt;https://github.com/capotej/youtube_fraiche&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uploadd and paperclip_uploadd:&lt;/strong&gt;
I wanted to upload and store images off-site (using paperclip/rails) on an server which has cheaper bandwidth rates than S3. Using rainbows, this tiny rack script has handled over a 1.5 million uploads at a peak of 10-15 uploads/sec. Also, it&amp;#8217;s been running for about 6 months now without a single crash. Thank you Eric Wong!
&lt;a href="https://github.com/capotej/uploadd"&gt;https://github.com/capotej/uploadd&lt;/a&gt; 
There is also a plugin for the popular paperclip gem to use uploadd as a storage backend transparently.
&lt;a href="https://github.com/capotej/paperclip_uploadd"&gt;https://github.com/capotej/paperclip_uploadd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mrskinner:&lt;/strong&gt;
Tiny javascript for making the site gutters clickable based on a fixed width layout:
&lt;a href="https://github.com/capotej/mrskinner/blob/master/mrskinner.js"&gt;https://github.com/capotej/mrskinner/blob/master/mrskinner.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;existential:&lt;/strong&gt;
Completely inspired by Nick Kallen&amp;#8217;s &lt;a href="http://pivotallabs.com/users/nick/blog/articles/272-access-control-permissions-in-rails"&gt;post&lt;/a&gt; on authorization, I wanted to extract that pattern into a rails plugin that I could use for all my projects. I use devise/existential for all my projects now.
&lt;a href="https://github.com/capotej/existential"&gt;https://github.com/capotej/existential&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;has_opengraph:&lt;/strong&gt;
Easy way to participate in opengraph and draw facebook like buttons. Just annotate your models with meta data, and draw it in your view easily.
&lt;a href="https://github.com/capotej/has_opengraph"&gt;https://github.com/capotej/has_opengraph&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;chewbacca:&lt;/strong&gt;
I kinda feel bad that I took a cool name for such a lame script. Anyway it&amp;#8217;s a set of rake tasks that provide a hair of abstraction above scp. Useful when you have a set of files locally that map to a different set of files remotely.
&lt;a href="https://github.com/capotej/chewbacca"&gt;https://github.com/capotej/chewbacca&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I already have tons of stuff in the works for 2011!&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/2546786852</link><guid>http://jcapote.tumblr.com/post/2546786852</guid><pubDate>Fri, 31 Dec 2010 17:29:00 -0500</pubDate></item><item><title>On Google Buzz</title><description>&lt;p&gt;&lt;i&gt;Summary&lt;/i&gt;: In this post I attempt to rationalize the creation of Google Buzz.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;How I see it&lt;br/&gt;&lt;/b&gt;Google Buzz is a subset of email, optimized for sharing information and discussing said information amongst a network of followers. I&amp;#8217;m sure Google noticed that a large number of users send short messages, occasionally accompanied by a link or an attached image, to the same people over and over. I know I do; Regardless of Twitter or Facebook, Email is still my preferred medium for propagating content to my close friends. In fact, the first browser add-on I install is the &amp;#8220;send via gmail&amp;#8221; to automate this process. So upon seeing Google Buzz, instead of seeing it as &amp;#8220;another social network&amp;#8221;, I saw it as a streamlining of my current link sharing workflow.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Sharing&lt;br/&gt;&lt;/b&gt;Sharing things on Google Buzz is pretty easy (although I&amp;#8217;m still waiting for my chrome extension). It&amp;#8217;s faster than sending out an email because you can create groups of those you would normally CC and you don&amp;#8217;t have to think about a subject line.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Private Groups&lt;/b&gt;&lt;br/&gt;I believe that this is Google Buzz&amp;#8217;s killer feature. As our social graphs increase and intersect/overlap, the importance of segregating information increases. For instance, your Mom/Boss/Girlfriend(s) seeing pictures of you at that raunchy party the other night. This is a common problem that anyone with a Facebook/Myspace can attest to having (at least once). Not just for privacy&amp;#8217;s sake but for the sake of your followers. I used to have every tweet posted to my Facebook but people complained that they didn&amp;#8217;t understand 99.9% of the things I posted (programming links/info usually). And inversely if I started posting non technical/silly things to Twitter, I&amp;#8217;ll lose the technical audience there (this is why &lt;a&gt;this&lt;/a&gt; app rules). Google Buzz allows me to share content with just the people I want (and discuss with the people I want).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Discussion&lt;br/&gt;&lt;/b&gt;Let&amp;#8217;s face it, trying to have a deep discussion is next to impossible on Twitter (not that this is bad). Meanwhile, Google Buzz inherits gmail&amp;#8217;s threaded conversation feature (one of it&amp;#8217;s best features) which makes discussing buzzed items a breeze. Also the &amp;#8220;Like&amp;#8221; concept is not to be underestimated, how many times have you seen email replies with &amp;#8220;+1&amp;#8221; in them? Or, if a discussion you don&amp;#8217;t care about keeps showing up on your stream you can simply Mute it. Crazy Speculation: This may be what&amp;#8217;s coming next for Google Groups.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Pain Points&lt;br/&gt;&lt;/b&gt;Nothing is perfect, and Google Buzz is surely is not. For one, it&amp;#8217;s, some say, &lt;i&gt;intrusive&lt;/i&gt;, arrival rubbed a lot of people the wrong way. You&amp;#8217;ll find all kinds of posts on the internet about how they feel betrayed by Google for forcing a social network down their throat. Others felt that their gmail was their &amp;#8220;work area&amp;#8221; and didn&amp;#8217;t want to bothered with such folly (understandably so). That&amp;#8217;s why I feel it should&amp;#8217;ve been deployed like this: Wave style invites and if you buzz someone that doesn&amp;#8217;t have an invite, they just get it like a regular email with a link on the bottom to join. The early adopters will bring in those they feel will like the service and use it with them. The other point is that you can&amp;#8217;t filter out buzzed tweets (when you tweet, Google Buzz will buzz it automatically) so you end seeing tweets twice.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Conclusion&lt;br/&gt;&lt;/b&gt;So in conclusion, will Buzz replace Twitter for me? No. But it will definitely replace those quickie emails I fire off to the same group of people over and over. I feel like they are trying to market Google Wave to a bigger, more mainstream audience. If that&amp;#8217;s the case, I look forward to see what else Google Buzz will bring to the table in the future.&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/390050440</link><guid>http://jcapote.tumblr.com/post/390050440</guid><pubDate>Sun, 14 Feb 2010 22:31:00 -0500</pubDate></item><item><title>On PHP Frameworks...</title><description>My Friend: I never realized there were so many PHP frameworks...&lt;br /&gt;&#13;
Me: That's cause they aren't smart enough to realize it's impossible to build abstractions without lambdas</description><link>http://jcapote.tumblr.com/post/245405012</link><guid>http://jcapote.tumblr.com/post/245405012</guid><pubDate>Sun, 15 Nov 2009 20:16:39 -0500</pubDate></item><item><title>Using Rack applications inside GWT Hosted mode</title><description>&lt;p&gt;This guide will show you how you can use JRuby to run any Rack application inside Google Web Toolkit&amp;#8217;s (GWT) hosted mode server so your interface and your backend are of the Same Origin.&lt;br/&gt;&lt;br/&gt;&lt;b&gt;Background&lt;/b&gt;&lt;b&gt; &lt;/b&gt;&lt;br/&gt;GWT has two ways of interacting with a server: GWT Remote Procedure Call (RPC) and plain HTTP (XHR). GWT-RPC is a high level library designed for interacting with server-side Java code. GWT-RPC implements the GWT Remote Service interface allowing you to call those methods from the user interface. Essentially, GWT handles the dirty work for you. However, it only works on Java backends that can implement that interface. Since most of my backends are Sinatra/Rack applications, I&amp;#8217;ll be using the plain HTTP library.&lt;br/&gt;&lt;br/&gt;&lt;b&gt;The problem&lt;/b&gt;&lt;br/&gt;Due to the restriction of the &lt;a href="http://en.wikipedia.org/wiki/Same_origin_policy"&gt;Same Origin&lt;/a&gt; policy, the interface served out of GWT&amp;#8217;s development, or Hosted Mode server can only make requests back to itself. If you were using real servlets or GWT&amp;#8217;s RemoteService this wouldn&amp;#8217;t be an issue; but since Rack applications listen on their own port, you cannot make requests from GWT to our application without resorting to something like JSONP or server-side proxying. This leaves you having to compile our interface to HTML/JS/CSS, which is lengthy process, and serve it from the origin of the Rack application to see our changes.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The solution&lt;/b&gt;&lt;br/&gt;Since I wanted to develop using GWT&amp;#8217;s development environment with a Rack backend, I devised a way to use jruby-rack to load arbitrary Rack applications alongside our interface.&lt;br/&gt;&lt;br/&gt;&lt;b&gt;First let&amp;#8217;s setup our environment:&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;1. Download and unpack the latest GWT for your platform (mine&amp;#8217;s being linux) and goto it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget &lt;a href="http://google-web-toolkit.googlecode.com/files/gwt-linux-1.7.0.tar.bz2"&gt;&lt;a href="http://google-web-toolkit.googlecode.com/files/gwt-linux-1.7.0.tar.bz2"&gt;http://google-web-toolkit.googlecode.com/files/gwt-linux-1.7.0.tar.bz2&lt;/a&gt;&lt;/a&gt;&lt;br/&gt;tar -xvjpf gwt-linux-1.7.0.tar.bz2&lt;br/&gt;cd gwt-linux-1.7.0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2 .Download the latest jruby-complete.jar:&lt;/p&gt;
&lt;pre&gt;&lt;code class="sh"&gt;wget &lt;a href="http://repository.codehaus.org/org/jruby/jruby-complete/1.3.1/jruby-complete-1.3.1.jar"&gt;&lt;a href="http://repository.codehaus.org/org/jruby/jruby-complete/1.3.1/jruby-complete-1.3.1.jar"&gt;http://repository.codehaus.org/org/jruby/jruby-complete/1.3.1/jruby-complete-1.3.1.jar&lt;/a&gt;&lt;/a&gt;&lt;br/&gt;mv jruby-complete-1.3.1.jar jruby-complete.jar&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3. Download the latest jruby-rack.jar&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget &lt;a href="http://repository.codehaus.org/org/jruby/rack/jruby-rack/0.9.4/jruby-rack-0.9.4.jar"&gt;&lt;a href="http://repository.codehaus.org/org/jruby/rack/jruby-rack/0.9.4/jruby-rack-0.9.4.jar"&gt;http://repository.codehaus.org/org/jruby/rack/jruby-rack/0.9.4/jruby-rack-0.9.4.jar&lt;/a&gt;&lt;/a&gt;&lt;br/&gt;mv jruby-rack-0.9.4.jar jruby-rack.jar&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Now let&amp;#8217;s create our GWT application&lt;/b&gt;&lt;b&gt; using&lt;/b&gt;&lt;b&gt; an exam&lt;/b&gt;&lt;b&gt;p&lt;/b&gt;&lt;b&gt;le Sinatra backend:&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;4. Create an app with webAppCreator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./webAppCreator -out MySinatra com.example.MySinatra&lt;br/&gt;cd MySinatra&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5. In order for this to work you have to package any gem dependencies your backend needs (sinatra, in our case) as jars within your application. For Sinatra it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; java -jar jruby-complete.jar -S gem install -i ./sinatra sinatra --no-rdoc --no-ri&lt;br/&gt; jar cf sinatra.jar -C sinatra .&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;6. Add jruby-complete.jar, jruby-rack.jar, sinatra.jar (and any other jars you&amp;#8217;ve created) to the libs target of your build.xml:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;target name="libs" description="Copy libs to WEB-INF/lib"&amp;gt;&lt;br/&gt; &amp;lt;mkdir dir="war/WEB-INF/lib" /&amp;gt;&lt;br/&gt; &amp;lt;copy todir="war/WEB-INF/lib" file="${gwt.sdk}/gwt-servlet.jar" /&amp;gt;&lt;br/&gt; &amp;lt;!-- Add any additional server libs that need to be copied --&amp;gt;&lt;br/&gt; &amp;lt;copy todir="war/WEB-INF/lib" file="${gwt.sdk}/jruby-complete.jar" /&amp;gt;&lt;br/&gt; &amp;lt;copy todir="war/WEB-INF/lib" file="${gwt.sdk}/jruby-rack.jar" /&amp;gt;&lt;br/&gt; &amp;lt;copy todir="war/WEB-INF/lib" file="${gwt.sdk}/sinatra.jar" /&amp;gt;&lt;br/&gt; &amp;lt;/target&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;7. Add these lines right after &amp;lt;web-app&amp;gt; in war/WEB-INF/web.xml:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;context-param&amp;gt;&lt;br/&gt; &amp;lt;param-name&amp;gt;rackup&amp;lt;/param-name&amp;gt;&lt;br/&gt; &amp;lt;param-value&amp;gt;&lt;br/&gt; require 'rubygems'&lt;br/&gt; require './lib/sinatra_app'&lt;br/&gt; map '/api' do&lt;br/&gt; run MyApp &lt;br/&gt; end&lt;br/&gt; &amp;lt;/param-value&amp;gt;&lt;br/&gt; &amp;lt;/context-param&amp;gt;&lt;br/&gt;&lt;br/&gt; &amp;lt;filter&amp;gt;&lt;br/&gt; &amp;lt;filter-name&amp;gt;RackFilter&amp;lt;/filter-name&amp;gt;&lt;br/&gt; &amp;lt;filter-class&amp;gt;org.jruby.rack.RackFilter&amp;lt;/filter-class&amp;gt;&lt;br/&gt; &amp;lt;/filter&amp;gt;&lt;br/&gt; &amp;lt;filter-mapping&amp;gt;&lt;br/&gt; &amp;lt;filter-name&amp;gt;RackFilter&amp;lt;/filter-name&amp;gt;&lt;br/&gt; &amp;lt;url-pattern&amp;gt;/api/*&amp;lt;/url-pattern&amp;gt;&lt;br/&gt; &amp;lt;/filter-mapping&amp;gt;&lt;br/&gt;&lt;br/&gt; &amp;lt;listener&amp;gt;&lt;br/&gt; &amp;lt;listener-class&amp;gt;org.jruby.rack.RackServletContextListener&amp;lt;/listener-class&amp;gt;&lt;br/&gt; &amp;lt;/listener&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: All you&amp;#8217;re doing here is passing the contents of a config.ru file into the &amp;lt;param-value&amp;gt; element for the &amp;lt;context-param&amp;gt; (make sure this is HTML encoded!). This states that any request to /api is to be handled by your Sinatra application and not GWT&amp;#8217;s Hosted mode servlet.&lt;br/&gt;&lt;br/&gt;8. Create your Sinatra backend and place it in war/WEB-INF/lib/sinatra_app.rb&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;require 'sinatra'&lt;br/&gt;require 'open-uri'&lt;br/&gt;class MyApp &amp;lt; Sinatra::Base&lt;br/&gt;&lt;br/&gt;  get '/showpage' do&lt;br/&gt;     open('&lt;a href="http://www.yahoo.com/"&gt;&lt;a href="http://www.yahoo.com"&gt;http://www.yahoo.com&lt;/a&gt;&lt;/a&gt;').read&lt;br/&gt;  end&lt;br/&gt;&lt;br/&gt;  get '/helloworld' do&lt;br/&gt;    'hello world'&lt;br/&gt;  end&lt;br/&gt;&lt;br/&gt;end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;9. Run your new awesome setup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ant hosted&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now when navigate to &lt;a href="http://localhost:8888/api/helloworld"&gt;http://localhost:8888/api/helloworld&lt;/a&gt; or &lt;a href="http://localhost:8888/api/showpage"&gt;http://localhost:8888/api/showpage&lt;/a&gt; you should see the Sinatra application being served via GWT.&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/145035194</link><guid>http://jcapote.tumblr.com/post/145035194</guid><pubDate>Sun, 19 Jul 2009 21:51:00 -0400</pubDate><category>jruby</category><category>rack</category><category>gwt</category></item><item><title>Useful Rails Routing tips</title><description>&lt;p&gt;Even though I have been using Rails for fun and profit for about 2 years now, I felt I never really used it&amp;#8217;s routing engine to its full potential. So I checked out new &lt;a target="_blank" title="Rails Routing from the outside in" href="http://guides.rubyonrails.org/routing_outside_in.html" id="qztr"&gt;Rails Routing from the outside in&lt;/a&gt; guide and discovered bunch of useful tricks that I (and maybe you) had no idea you could do. Here they are:&lt;/p&gt;
&lt;h3&gt;Multiple resource definitions on a single line&lt;/h3&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;map.resources :photos, :books, :videos&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Impose a certain format for resource identifiers&lt;/h3&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;map.resources :photos, :requirements =&amp;gt; { :id =&amp;gt; /[A-Z][A-Z][0-9]+/ }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt;This way, /photos/3 would not work, but /photos/DA321 would.&lt;/p&gt;
&lt;h3&gt;Friendlier action names&lt;/h3&gt;
&lt;p&gt;Say for your application &amp;#8216;create&amp;#8217; and &amp;#8216;change&amp;#8217; make more sense than the default &amp;#8216;new&amp;#8217; and &amp;#8216;edit&amp;#8217; you can do&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;map.resources :photos, :path_names =&amp;gt; { :new =&amp;gt; 'make', :edit =&amp;gt; 'change' }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also do this site-wide also, in your environment.rb&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;config.action_controller.resources_path_names = { :new =&amp;gt; 'make', :edit =&amp;gt; 'change' }&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Trim the fat off resources with :only and :except &lt;br/&gt;&lt;/h3&gt;
&lt;p&gt;When you use map.resources, rails generates 7 restful routes for that resource; But what if that resource only needed to be seen and listed, never edited or created?&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;map.resources :photos, :only =&amp;gt; [:index, :show]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If your application uses alot of map.resources calls but not neccesarily all its generated routes, you can save memory this way.&lt;/p&gt;
&lt;h3&gt;Adding extra routes to your resources&lt;br/&gt;&lt;/h3&gt;
&lt;p&gt;Instead of fighting the map.resources generator by placing a horror like this atop your routes.rb&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;map.connect '/photos/:id/preview', { :controller =&amp;gt; 'photos', :action =&amp;gt; 'preview' }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt; You can do this to your already mapped resource&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;map.resources :photos, :member =&amp;gt; { :preview =&amp;gt; :get }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt; This will map all GET&amp;#8217;s to /photos/3 to the preview action of your photos controller&lt;br/&gt;&lt;br/&gt; This can also be  used in collections instead of singular members, just change :member to :collection&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;map.resources :photos, :collection =&amp;gt; { :search =&amp;gt; :get }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will give you /photos/search and hit the search action within the photos controller&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/67873462</link><guid>http://jcapote.tumblr.com/post/67873462</guid><pubDate>Thu, 01 Jan 2009 19:50:00 -0500</pubDate></item><item><title>So you want to click that button?</title><description>&lt;p&gt;I stumbled upon &lt;a href="http://clickthatbutton.com"&gt;http://clickthatbutton.com&lt;/a&gt; during my routine lurking of &lt;a href="http://news.ycombinator.com"&gt;hacker news&lt;/a&gt;. After being amused for about 10 seconds,  I decided to take it to the next level; I wanted to click on it really, really fast. After going through a few solutions (simple js while loop in firebug, then curl/wget) and failing, the idea of using selenium popped into my head. So I went off to their &lt;a href="http://selenium-ide.openqa.org/download.jsp"&gt;site&lt;/a&gt; and installed the extension. I figured a simple recording of the mouse event, then wrapping it around a loop in selenium would do the trick, but I quickly found that selenium doesn&amp;#8217;t support loops. Not to be stopped, I searched google and ended up with &lt;a href="http://51elliot.blogspot.com/2008/02/selenium-ide-goto.html"&gt;this&lt;/a&gt;. After installing the plugin for selenium (a plugin for a plugin!?) and restarting firefox, I tried it again and to my surprise it worked! The click counter was going up steadily on its own (18k clicks and counting). Here is my selenium test case for those of you following along:&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&amp;gt;
&amp;lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&amp;gt;
&amp;lt;head profile="http://selenium-ide.openqa.org/profiles/test-case"&amp;gt;
&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&amp;gt;
&amp;lt;link rel="selenium.base" href="http://clickthatbutton.com/" /&amp;gt;
&amp;lt;title&amp;gt;haha&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;table cellpadding="1" cellspacing="1" border="1"&amp;gt;
&amp;lt;thead&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td rowspan="1" colspan="3"&amp;gt;haha&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/thead&amp;gt;&amp;lt;tbody&amp;gt;
&amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;open&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;/&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;store&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;x&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;while&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;storedVars['x'] == storedVars['x']&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;click&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;submit&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;endWhile&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Just paste that into a file, open it with selenium ide, hit play and you should be good to go.&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/56866975</link><guid>http://jcapote.tumblr.com/post/56866975</guid><pubDate>Wed, 29 Oct 2008 00:05:00 -0400</pubDate></item><item><title>Arrow key navigation for text fields</title><description>&lt;p&gt;Here is a class for enabling the use of arrow keys to navigate through a grid of input fields: (using mootools)&lt;/p&gt;
&lt;pre&gt;&lt;code class="javascript"&gt;
var FocusMover = new Class({

	initialize: function(sel, col_num){

		this.sel = sel
		this.col_num = col_num
		this.inputs = $$(this.sel)
		this.current_focus = 0

		var self = this

		this.inputs.each(function(item, index){
			item.addEvent('keydown',function(key){
				$try(function(){
					self[key.key]()
				})
			})
			item.addEvent('focus',function(e){
				self.refresh(e)
			})

			item.set('myid', index)
		})

		this.inputs[0].focus()

	},


	refresh: function(e){
		this.current_focus = e.target.get('myid')
	},

	down: function(){
		i = parseInt(this.current_focus) + parseInt(this.col_num)
		this.inputs[i].focus()
	},

	up: function(){
		i = parseInt(this.current_focus) - parseInt(this.col_num)
		this.inputs[i].focus()
	},

	left: function(){
		i = parseInt(this.current_focus) - 1
		this.inputs[i].focus()
	},

	right: function(){
		i = parseInt(this.current_focus) + 1
		this.inputs[i].focus()
	}

})

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, the constructor takes two arguments: a selector (which should return a list of all your input fields), and the number of input field columns. So for a 4x2 table, you would set it up like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="javascript"&gt;
var FM = new FocusMover('#mytable input', 4)
&lt;/code&gt;&lt;/pre&gt;</description><link>http://jcapote.tumblr.com/post/54266325</link><guid>http://jcapote.tumblr.com/post/54266325</guid><pubDate>Sun, 12 Oct 2008 20:41:00 -0400</pubDate><category>programming</category></item><item><title>Tabbing through fields vertically</title><description>&lt;p&gt;Sometimes it&amp;#8217;s useful to switch the browser&amp;#8217;s default tabbing behavior (left to right) to the opposite (top to bottom) when your input fields are in a grid layout instead the of the usual single column layout. Having to do this manually is a real pain, especially for large grids; So here is a solution in javascript, using mootools:
&lt;pre&gt;&lt;code class="javascript"&gt;
window.addEvent('domready', function(){
    var trs = $$('#mytable tr')
    var accum = 0
    trs.each(function(tr, trindex){
        accum = trindex + 1
        tr.getChildren().each(function(td, tdindex){
            td.getChildren('input')[0].tabIndex = accum
            accum = accum + trs.length
        })	    
    })
})
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/54058512</link><guid>http://jcapote.tumblr.com/post/54058512</guid><pubDate>Sat, 11 Oct 2008 04:54:00 -0400</pubDate><category>programming</category></item><item><title>Why MooTools (or Why not JQuery)</title><description>&lt;p&gt;I&amp;#8217;ve been toying around with MooTools a bit lately, and I&amp;#8217;ve found the experience quite enjoyable and refreshing. Naturally, I &lt;a href="http://twitter.com/capotej/statuses/939831956"&gt;twittered&lt;/a&gt; about it and went along my merry way. Moments later (and much to my surprise), I had a direct message from John Resig himself asking &amp;#8220;Why, what&amp;#8217;s wrong with jQuery?&amp;#8221;. I was pretty taken aback that he would take time from his surely busy day to message a total stranger in an effort to improve his project or at least gain an insight in the everyday life of a js developer (it&amp;#8217;s not like DHH would personally message people that are dumping rails to use merb). I figured he deserved a straight, honest answer; One that at least would be longer than &lt;a href="http://twitter.com/capotej/statuses/940082809"&gt;140 characters&lt;/a&gt; (even though I managed to use every single one). So it begs the question, Why MooTools?&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;b&gt;Class support.&lt;/b&gt;&lt;br/&gt;JQuery&amp;#8217;s SQL-like syntax is fine for quick and dirty javascripting, but eventually you&amp;#8217;ll want real classes to structure your UI logic.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;It smells, feels and tastes like regular javascript.&lt;/b&gt;&lt;br/&gt;JQuery doesn&amp;#8217;t even look like javascript, which isn&amp;#8217;t necessarily a bad thing, since that&amp;#8217;s kind of their goal. MooTools however, feels like just an extension of the language (more on this at point #9).&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;&lt;b&gt;Faster.&lt;/b&gt;&lt;br/&gt;&lt;a href="http://mootools.net/slickspeed/"&gt; &amp;#8216;Nuff Said&lt;/a&gt;&lt;/strike&gt; EDIT: This was pointed out to be false; It is only faster in certain cases (such as mine, WebKit nightly on OS X).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Robert Penner&amp;#8217;s easing equations baked right in.&lt;/b&gt;&lt;br/&gt;This could just be me, but I find the animations that mootools creates are alot smoother than JQuery&amp;#8217;s (especially the easing).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Creating new DOM elements is a snap.&lt;/b&gt;&lt;br/&gt;Need to create a dom element? var el = new Element(&amp;#8216;a&amp;#8217;, { &amp;#8216;href&amp;#8217;: &amp;#8216;juliocapote.com&amp;#8217;}); Done.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Modular. &lt;/b&gt;&lt;br/&gt;I like that I can just build and pull down a moo.js that only contains the functionality I need.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Better Documented.&lt;/b&gt;&lt;br/&gt;Or at least, its faster to find what you need.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Easier to hack on and extend.&lt;/b&gt;&lt;br/&gt;While I haven&amp;#8217;t personally delved into the internals of either system, the consensus seems to be that jquery is an unintelligible mess when it comes to modifying how it works.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Prototype Approach (versus a namespaced approach)&lt;/b&gt;&lt;br/&gt;This is really just matter of preference; MooTools achieves it&amp;#8217;s magic by just extending the prototypes of common objects (Array, String, etc); While this is obstrusive, it makes for shorter, more natural code. JQuery does its thing via a main object (which you can name, hence the namespace), that you wrap around whatever you want to make magical; This is unobstrusive, but you pay for that by having to wrap anything you want to use (which ends up being everything). It basically boils down to arr.each(fn) vs $.each(arr, fn)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;It&amp;#8217;s not a revolution.&lt;/b&gt;&lt;br/&gt;It feels as if JQuery is trying to take on the world (it seems like it too, since its now included with visual studio and the nokia sdk). However, I&amp;#8217;m not; I&amp;#8217;m just trying to write some javascript here.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;It&amp;#8217;s not like I&amp;#8217;m never going to use JQuery again; It simply isn&amp;#8217;t my default js framework any longer.&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/52467447</link><guid>http://jcapote.tumblr.com/post/52467447</guid><pubDate>Tue, 30 Sep 2008 13:26:00 -0400</pubDate><category>programming</category></item><item><title>I would buy and frame this.</title><description>&lt;img src="http://24.media.tumblr.com/Wi8E7COHkehgj6n97ZLCLlJSo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I would buy and frame this.&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/52369865</link><guid>http://jcapote.tumblr.com/post/52369865</guid><pubDate>Mon, 29 Sep 2008 22:30:46 -0400</pubDate></item><item><title>Highlight link based on current page in rails</title><description>&lt;p&gt;This is common pattern in website navigation, where it highlights the link (usually by setting class=&amp;#8221;active&amp;#8221;) that took you to the current page while you are on that page.&lt;/p&gt;
&lt;p&gt;First, define a helper:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;  def is_active?(page_name)
    "active" if params[:action] == page_name
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then call it in your link_to&amp;#8217;s in your layout as such:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;
link_to 'Home', '/', :class =&amp;gt; is_active?("index")
link_to 'About', '/about', :class =&amp;gt; is_active?("about")
link_to 'contact', '/contact', :class =&amp;gt; is_active?("contact")

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This effect is achieved due to how link_to handles being passed nil for its :class, so when is_active? returns nil (because its not the current page), link_to outputs nothing as its class (not class=&amp;#8221;&amp;#8221; as you might expect).&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/52081481</link><guid>http://jcapote.tumblr.com/post/52081481</guid><pubDate>Sat, 27 Sep 2008 22:47:00 -0400</pubDate><category>programming</category></item><item><title>Git Server tutorial</title><description>&lt;p&gt;good git server tutorial, &lt;a href="http://blog.commonthread.com/2008/4/14/setting-up-a-git-server"&gt;http://blog.commonthread.com/2008/4/14/setting-up-a-git-server&lt;/a&gt;&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/52055667</link><guid>http://jcapote.tumblr.com/post/52055667</guid><pubDate>Sat, 27 Sep 2008 17:20:00 -0400</pubDate></item><item><title>No way.</title><description>&lt;p&gt;I&amp;#8217;m sure we&amp;#8217;ve all been in a variant of this situation&amp;#8230;&lt;/p&gt;
&lt;pre&gt;Me:  I'd like to talk to you about something...
Him: Let me guess - you want to use Smalltalk.
Me:  Er, no...
Him: Lisp?
Me: Right.
Him:  No way.&lt;/pre&gt;

&lt;p&gt;Taken from &lt;a href="http://www.flownet.com/gat/jpl-lisp.html?dupe=with_honor"&gt;here&lt;/a&gt;&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/50284462</link><guid>http://jcapote.tumblr.com/post/50284462</guid><pubDate>Mon, 15 Sep 2008 15:10:04 -0400</pubDate></item><item><title>So true.</title><description>&lt;img src="http://24.media.tumblr.com/Wi8E7COHkdm01jnpKiqUTody_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;So true.&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/49186851</link><guid>http://jcapote.tumblr.com/post/49186851</guid><pubDate>Sun, 07 Sep 2008 22:08:18 -0400</pubDate></item><item><title>This made my morning.</title><description>&lt;img src="http://25.media.tumblr.com/Wi8E7COHkd5un3p1Wd5IWf9P_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This made my morning.&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/47654453</link><guid>http://jcapote.tumblr.com/post/47654453</guid><pubDate>Wed, 27 Aug 2008 14:52:47 -0400</pubDate></item><item><title>The difference between a computer scientist and an electrical engineer</title><description>&lt;a href="http://philip.greenspun.com/humor/eecs-difference-explained"&gt;The difference between a computer scientist and an electrical engineer&lt;/a&gt;: &lt;p&gt;I try to keep this article in mind whenever I’m designing anything…&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/46875120</link><guid>http://jcapote.tumblr.com/post/46875120</guid><pubDate>Thu, 21 Aug 2008 15:58:36 -0400</pubDate></item><item><title>Why I am excited about JRuby/Rails</title><description>&lt;p&gt;There are some new developments ripening on the JRuby/Rails front that&amp;#8217;s going to make things awesome in the coming months:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Thread safe rails in 2.2, see &lt;a title="Thread Safe Rails 2.2" href="http://weblog.rubyonrails.org/2008/8/16/josh-peek-officially-joins-the-rails-core"&gt;announcment&lt;/a&gt; and what it means &lt;a title="Headius on thread safe rails" href="http://blog.headius.com/2008/08/qa-what-thread-safe-rails-means.html"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;JDBC Connection pooling, see &lt;a title="JDBC connection pooling on glassfish" href="http://blog.linkedin.com/blog/2008/08/jdbc-connection.html"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Can&amp;#8217;t wait&amp;#8230;&lt;/p&gt;</description><link>http://jcapote.tumblr.com/post/46737450</link><guid>http://jcapote.tumblr.com/post/46737450</guid><pubDate>Wed, 20 Aug 2008 16:21:49 -0400</pubDate></item><item><title>Domenico DeMarco and pizza as art</title><description>&lt;a href="http://www.37signals.com/svn/posts/1203-domenico-demarco-and-pizza-as-art"&gt;Domenico DeMarco and pizza as art&lt;/a&gt;</description><link>http://jcapote.tumblr.com/post/46669015</link><guid>http://jcapote.tumblr.com/post/46669015</guid><pubDate>Wed, 20 Aug 2008 05:51:18 -0400</pubDate></item><item><title>Sivers/Ferriss interview that will make you think</title><description>&lt;a href="http://www.37signals.com/svn/posts/1196-siversferriss-interview-that-will-make-you-think"&gt;Sivers/Ferriss interview that will make you think&lt;/a&gt;</description><link>http://jcapote.tumblr.com/post/46033766</link><guid>http://jcapote.tumblr.com/post/46033766</guid><pubDate>Fri, 15 Aug 2008 01:24:20 -0400</pubDate></item></channel></rss>
