ActsAsFlinn http://actsasflinn.com/articles.rss en-us 40 $ ./script/plugin install acts_as_flinn Snippy is a Freaking Ripoff of Pastie <div style="float:right"> <a href="http://www.flickr.com/photos/lollyknit/336511240/"><img src="http://actsasflinn.com/files/scissors.jpg" alt="Scissor Kit on Flickr" style="width:250px" /></a><br /> Scissor Kit on Flickr by <a href="http://www.flickr.com/photos/lollyknit/">LollyKnit</a> </div> <h2><a href="http://github.com/actsasflinn/snippy/tree/master">Snippy</a> is a Freaking Ripoff of Pastie (and I did the ripping ;-)</h2> <p><a href="http://github.com/actsasflinn/snippy/tree/master">Snippy</a> is an open source clone of <a href="http://blog.pastie.org/">Josh Goebel&rsquo;s</a> <a href="http://pastie.org">Pastie</a>.</p> <p>A lot of Pastie users (including me) wanted a private version. Snippy fills that void &ndash; enjoy.</p> <p>I wrote it using Ruby on Rails 2.1 as a weekend project (about 2 months ago and I&#8217;m just now getting it out). I felt like one of the best features of Pastie is code highlighting so I made it a priority. Code highlighting is accomplished using a custom renderer with <a href="http://ultraviolet.rubyforge.org/">Ultraviolet</a>. The <a href="http://ts.freelancing-gods.com/">Thinking Sphinx</a> plugin has been on my radar for a little while now so I felt like it was a good time to throw that in.</p> <h2>On Github</h2> <p>Git has also been on my radar for a little while. So I figured I would host the project at Github &#8211; everyone wins. Get the source on <a href="http://github.com/actsasflinn/snippy/tree/master">Github</a>.</p> <h2>Install</h2> <ol> <li>git clone git://github.com/actsasflinn/snippy.git</li> <li>cd snippy</li> <li>cp config/database.yml.example config/database.yml</li> <li>rake db:create</li> <li>rake db:migrate</li> <li>rake bootstrap</li> <li>rake thinking_sphinx:configure</li> <li>rake thinking_sphinx:index</li> <li>rake thinking_sphinx:start</li> <li>./script/server</li> <li>Start Snipping</li> </ol> Wed, 03 Sep 2008 21:50:00 -0400 urn:uuid:e4c34b52-4601-4541-8eaa-f8cc2e445f59 http://www.actsasflinn.com/articles/2008/09/03/snippy-is-a-freaking-ripoff-of-pastie#comments Rails Ruby snippy pastie rails weekend http://www.actsasflinn.com/trackbacks?article_id=snippy-is-a-freaking-ripoff-of-pastie&day=03&month=09&year=2008 http://www.actsasflinn.com/articles/2008/09/03/snippy-is-a-freaking-ripoff-of-pastie 5 Reasons IE8 Will Rule over Firefox <p><img src="http://actsasflinn.com/files/ie_ff_cake.jpg" alt="IE Cake" style="width:240px;float:right" /></p> <ol> <li>Developers</li> <li>Developers</li> <li>Developers</li> <li>Developers</li> <li>Developers&#8230;</li> </ol> <p>So you may have heard that <a href="http://www.microsoft.com/windows/internet-explorer/beta/"><span class="caps">IE8</span> Beta 2 Shipped</a>. It&#8217;s awesome&#8230;relative to any other previous release of IE. It&#8217;s like the Windows XP of Internet Explorers.</p> <p>I&#8217;ve been developing web apps for a long time&#8230; which means I obligatorily hate IE. I still do hate it but I&#8217;m surprised at how good a release Microsoft has shipped. The look and feel is less bubble gum and a little more crisp. There is even a developer tool that&#8217;s almost as good as Firebug&#8230; no really. In addition to the dom browser there&#8217;s actually a <strong>javascript debugger in IE!</strong> I&#8217;m really amazed. They did manage to sneak in some hook ups to <span class="caps">MSN</span>&#8217;s crappy services but hey what do you expect?</p> <p>I actually think there is something to the developer tools in <span class="caps">IE8</span>. Microsoft is actually listening to the biggest criticisms coming from the web development community about how difficult it is to develop for IE. I work on some fairly high profile sites along with some pretty large teams for names you&#8217;ve heard of (Time, Sports Illustrated, Turner, etc.) and I&#8217;m seeing the vast majority of web developers using Macs with Firefox (and Firebug of course). Microsoft really used to cater to developers but the web has always been one of the hardest markets for Microsoft to capture developer market share in. Why? Because Microsoft has made the web suck and our jobs a lot harder. But I think they are starting to get it.</p> <p>So will <span class="caps">IE8</span> rule over Firefox&#8230;not for me but I&#8217;m sure it will for the countless masses still using IE. The side benefit for all of us web slaves is an easier to use and program for version of IE. Now please Microsoft just phase out <span class="caps">IE6</span>!</p> <p><a href="http://www.spreadfirefox.com/node&#38;id=245838&#38;t=305"><img border="0" alt="Firefox 3" title="Firefox 3" src="http://sfx-images.mozilla.org/affiliates/Buttons/firefox3/110x32_best-yet.png"/></a></p> <p>Sorry had to put that there ;-)</p> Thu, 28 Aug 2008 23:39:00 -0400 urn:uuid:39ea15da-15eb-4490-9edd-4ad97270bbb8 http://www.actsasflinn.com/articles/2008/08/28/5-reasons-ie8-will-rule-over-firefox#comments Random Rants ie hate http://www.actsasflinn.com/trackbacks?article_id=5-reasons-ie8-will-rule-over-firefox&day=28&month=08&year=2008 http://www.actsasflinn.com/articles/2008/08/28/5-reasons-ie8-will-rule-over-firefox Dear Twitter Users, <p>I don&#8217;t care what you&#8217;re up to. That is all.</p> Wed, 06 Aug 2008 22:06:00 -0400 urn:uuid:0444581f-9311-4c6c-afd3-93dd988c03ff http://www.actsasflinn.com/articles/2008/08/06/dear-twitter-users#comments Random Rants who cares about twitter http://www.actsasflinn.com/trackbacks?article_id=dear-twitter-users&day=06&month=08&year=2008 http://www.actsasflinn.com/articles/2008/08/06/dear-twitter-users "5 Reasons My Next App Is Going to Be In Assembly".gsub('Assembly', 'Merb') <div style="float:right"><a href="http://rubyrags.com/products/2"><img src="http://rubyrags.com/pictures/0000/0005/enterprise_ready.png?1197494069" alt="Yes, Enterprise Ready" /></a></div> <h2>1. Rails: So Easy A Caveman Can Do It!</h2> <p>I&#8217;m doing Rails over three years now, right around the time all the <a href="http://cakephp.org">bullshit</a> <a href="http://biscuitproject.tigris.org/"><span class="caps">PHP</span></a> <a href="http://phpontrax.org/">clones</a> started cropping up. I switched to Ruby on Rails from <span class="caps">PHP</span> because <strong>Rails is brilliant</strong>. ActiveRecord makes dealing with the database a <a href="http://geico.com/">so easy a caveman can do it.</a> I&#8217;m 100% certain Rails&#8217; uptake can be attributed to AR. That&#8217;s awesome and all but Rails has seriously gotten bloated in it&#8217;s chase to be <a href="http://agilewebdevelopment.com/plugins/acts_as_enterprisey">enterprisey</a>. ActiveResource, Timezones, mass-assignment, i18n&#8230; next bloat will be full text search <strong>mark my words</strong>.</p> <h2>2. You Miss <span class="caps">PHP</span> Don&#8217;t You?</h2> <p>The niceties of Rails are great but don&#8217;t you miss the simplicity and control of <span class="caps">PHP</span>? I certainly don&#8217;t miss the <strong><span class="caps">PHP</span> because it sucks</strong>. I came for the Rails and stayed for the Ruby &#8211; writing non-Rails Ruby apps for a while now and loving Ruby. I&#8217;m <a href="http://actsasflinn.com/articles/2008/06/16/json-p-rack-handler">crushing on Merb and Halcyon lately</a>. <strong>I love Merb because I can screw with it!</strong></p> <h2>3. I hacked Merb</h2> <p>In 20m I hacked the caching system to use memcached (the gem). In 10 minutes I dropped in a custom <span class="caps">JSON</span>-P rack handler. <strong>30 minutes with Merb and I&#8217;ve boosted <span class="caps">API</span> performance 250%!</strong> All while dropping a shitload of bloat I don&#8217;t need and tightening my own code.</p> <h2>4. Merb Is A Sexy</h2> <p>It gives me the feeling I have control again and <u>whats sexier than dominating Merb?</u> <a href="http://merbivore.com/">Merb</a> started out as a hack &#8211; just a few lines of Ruby on top of Mongrel&#8230; OK it&#8217;s not assembly &#8211; close enough.</p> <h2>5. Merb for Job Security</h2> <p>When the bubble 2.0 bursts you&#8217;re going to be fighting for a job with thousands of &#8220;Rails developers&#8221; that have read the Agile book and think they know Rails. I&#8217;ve interviewed probably a dozen candidates that &#8220;have Rails experience&#8221; but have nothing to show than internal app used by 20 people (if that). Writing Web apps is much more than <span class="caps">CRUD</span>. Get over it already.</p> Sun, 03 Aug 2008 23:06:00 -0400 urn:uuid:4dee5503-d3a2-4dfe-98d9-4d42daaf7fe3 http://www.actsasflinn.com/articles/2008/08/03/5-reasons-my-next-app-is-going-to-be-in-assembly-gsub-assembly-merb#comments Rails Rants Ruby ruby merb rails rants http://www.actsasflinn.com/trackbacks?article_id=5-reasons-my-next-app-is-going-to-be-in-assembly-gsub-assembly-merb&day=03&month=08&year=2008 http://www.actsasflinn.com/articles/2008/08/03/5-reasons-my-next-app-is-going-to-be-in-assembly-gsub-assembly-merb Gregory Brown of Ruby Mendicant, Prawn, Ruport Fame Visits Hartford.rb <p>Last night the Hartford Ruby Brigade was treated to a few excellent talks by <a href="http://www.oreillynet.com/pub/au/2593">Gregory Brown</a> the Ruby Mendicant, Prawn, Ruport and <span class="caps">PDF</span> Writer maintainer. The talk started out with a Matrix like hack of <a href="http://rubyquiz.com/quiz59.html">RRobots</a>. The group did Ruby Quiz #59 the month before and had a death match&#8230; Gregory hacked the engine and destroyed all within 1 tick. Checkout the slides how he explains the ObjectSpace hack. He also gave a few other mini-talks about Ruport, <span class="caps">API</span> design, <span class="caps">PDF</span> Writer, Prawn and (my favorite) the open source farmers market.</p> <object width="400" height="300"> <param name="allowfullscreen" value="true" /> <param name="allowscriptaccess" value="always" /> <param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1428070&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /> <embed src="http://www.vimeo.com/moogaloop.swf?clip_id=1428070&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object><br /><a href="http://www.vimeo.com/1428070?pg=embed&#38;sec=1428070">Hartford.rb 2008.07.28 &#8211; Intro / Cheating at RRobots</a> from <a href="http://www.vimeo.com/user639017?pg=embed&#38;sec=1428070">Gregory Brown</a> on <a href="http://vimeo.com?pg=embed&#38;sec=1428070">Vimeo</a>. <object width="400" height="327"> <param name="allowfullscreen" value="true" /> <param name="allowscriptaccess" value="always" /> <param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1454574&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /> <embed src="http://www.vimeo.com/moogaloop.swf?clip_id=1454574&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="327"></embed></object><br /><a href="http://www.vimeo.com/1454574?pg=embed&#38;sec=1454574">Ruport : Finally Useful After 3 Years</a> from <a href="http://www.vimeo.com/user639017?pg=embed&#38;sec=1454574">Gregory Brown</a> on <a href="http://vimeo.com?pg=embed&#38;sec=1454574">Vimeo</a>. <object width="400" height="300"> <param name="allowfullscreen" value="true" /> <param name="allowscriptaccess" value="always" /> <param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1446350&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /> <embed src="http://www.vimeo.com/moogaloop.swf?clip_id=1446350&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object><br /><a href="http://www.vimeo.com/1446350?pg=embed&#38;sec=1446350">Hartford.rb 2008.07.28 &#8211; Designing APIs That Don&#8217;t Suck</a> from <a href="http://www.vimeo.com/user639017?pg=embed&#38;sec=1446350">Gregory Brown</a> on <a href="http://vimeo.com?pg=embed&#38;sec=1446350">Vimeo</a>. Tue, 29 Jul 2008 20:55:00 -0400 urn:uuid:06636821-a713-4195-9ca4-17f9b9c06142 http://www.actsasflinn.com/articles/2008/07/29/gregory-brown-of-ruby-mendicant-prawn-ruport-fame-visits-hartford-rb#comments Ruby ruby rrobots hartford.rb http://www.actsasflinn.com/trackbacks?article_id=gregory-brown-of-ruby-mendicant-prawn-ruport-fame-visits-hartford-rb&day=29&month=07&year=2008 http://www.actsasflinn.com/articles/2008/07/29/gregory-brown-of-ruby-mendicant-prawn-ruport-fame-visits-hartford-rb Ruby Constipation <p><a href="http://www.zazzle.com/ruby_constipation_shirt-235020656743649903"><img src="http://actsasflinn.com/files/ruby-constipation-design.png" alt="Ruby Constipation" style="float:right;clear:both" /></a> So it seems Ruby is constipated. I had fun with this one today&#8230; At work a few of us were tracking down an missing constant so we needed to be sure one of our config/initializers was running.</p> <p>&ldquo;add puts &quot;poop&quot;&rdquo;<br /> &ldquo;no wait, p &quot;poop&quot;&rdquo;</p> <p>So I turned it into a shirt &#8211; <a href="http://www.zazzle.com/ruby_constipation_shirt-235020656743649903">Buy It!</a></p> Fri, 25 Jul 2008 00:16:00 -0400 urn:uuid:5ea9f3f6-cba0-4175-aedb-060c3013faf1 http://www.actsasflinn.com/articles/2008/07/25/ruby-constipation#comments Ruby ruby rails t shirt awesome http://www.actsasflinn.com/trackbacks?article_id=ruby-constipation&day=25&month=07&year=2008 http://www.actsasflinn.com/articles/2008/07/25/ruby-constipation JSON-P Rack Handler <p class="note">Updated 2008-06-19 &#8211; better support Halcyon</p> <h2><span class="caps">JSON</span>-P Rack Handler</h2> <h3>Juicing Ruby</h3> <p>I&rsquo;ve been trying to find ways to squeeze all the juice out of Ruby lately. So many blog posts talk about how Rails doesn&rsquo;t scale, Ruby is slow, blah blah. I had a convo with another developer at work today that went something like this:</p> <p>Me: if we&rsquo;re willing to do anything for performance we&rsquo;d we just switch to Java</p> <p>Jared: Yeah let&rsquo;s not do that.</p> <p>Switching to Java would be a big trade off in performance but also in development time. That&rsquo;s a big trade off that none of us around here think is worth. That&rsquo;s where this Rack handler comes in.</p> <h3><span class="caps">JSON</span>-P Caching</h3> <p>I&rsquo;ve posted before about <a href="http://actsasflinn.com/articles/2008/04/20/jsonp-on-rails-with-jquery">how to use <span class="caps">JSON</span>-P in Rails</a> and <a href="http://actsasflinn.com/articles/2008/06/13/cross-domain-restful-json-p-with-rails#railscachingjsonp">how to cache <span class="caps">JSON</span>-P in Rails</a> with fairly decent results (500+ reqs/sec) but I felt like I could do better. Action caching always seemed like the best way to cache the full <span class="caps">JSON</span> output of a request but the fact that jQuery uses a dynamic callback takes action caching out of the equation.</p> <h3>Speeding up <span class="caps">JSON</span>-P</h3> <p>500+ reqs/sec is good and all but I felt like if I could action cache then somehow pad that cached <span class="caps">JSON</span> result with the callback I&rsquo;d get better performance. I thought I&rsquo;d see what Merb could offer on the <span class="caps">JSON</span>-P front. In my quest to juice Ruby my test setup looks like this: Merb, Datamapper, Memcached (the c gem), Memcached (the server) and Ebb. I&rsquo;m really impressed with Merb and Datamapper in terms of development and I&rsquo;m equally impressed with Rack and Ebb for performance.</p> <p>I read recently it&rsquo;s possible to <a href="http://groups.google.com/group/rack-devel/browse_thread/thread/8d5a8199d60a0894">use Rack to filter results to gzip output</a>, which got me thinking. Why not try to do the same to pad my action cached <span class="caps">JSON</span>. Well it is possible and <strong>I&rsquo;m squeezing out <span class="caps">JSON</span>-P at ~1200 reqs/sec with the <span class="caps">JSON</span>-P Rack Handler</strong> with my test stack.</p> <h3><span class="caps">JSON</span>-P Rack Handler</h3> <pre><code> # config/jsonp.rb class JsonP def initialize(app) @app = app end def call(env) status, headers, response = @app.call(env) request = Rack::Request.new(env) response = pad(request.params.delete('callback'), response) if request.params.include?('callback') [status, headers, response] end def pad(callback, response, body = "") response.each{ |s| body &lt;&lt; s } "#{callback}(#{body})" end end</code></pre> <h3>Config</h3> <pre><code> # config/rack.rb require 'config/jsonp' use JsonP run Merb::Rack::Application.new </code></pre> <h3>In Halcyon</h3> <pre><code> # runner.ru ... require 'config/jsonp.halcyon' use JsonP run Halcyon::Runner.new </code></pre> <h3>Rails Support Soon</h3> <p>One last thing&#8230; whenever Rails starts using Rack, you&rsquo;ll be able to use this in your Rails app.</p> <p class="note">About Me: I&rsquo;m a developer with <a href="http://www.sportstechinc.com/">Sports Technologies</a>, a Rails firm specializing in community focused web applications aimed at sports and entertainment. We&rsquo;re always looking for Rails talent, if you&rsquo;re looking to work on rewarding high profile projects with a seasoned team of professionals give us a shout.</p> Mon, 16 Jun 2008 21:58:00 -0400 urn:uuid:59de356f-8b0d-4d97-b28f-f58660c02ba9 http://www.actsasflinn.com/articles/2008/06/16/json-p-rack-handler#comments Rails AJAX json p caching merb rack halcyon http://www.actsasflinn.com/trackbacks?article_id=json-p-rack-handler&day=16&month=06&year=2008 http://www.actsasflinn.com/articles/2008/06/16/json-p-rack-handler Cross domain RESTful JSON-P with Rails <h2>Rails based JSON-P</h2> <p>For the last 2 months I've been working on part of a project for a large publisher rolling out some new web services that use Rails based JSON to display comments on static web pages. This project has been a learning experience for nearly everyone involved on the Rails side and on the front end development side. We&rsquo;ve overcome a number of limitations with the lack of a safe data transport in web browsers and limitations in the way Rails handles JSON-P and cross site REST. Some of the problems are unique to the solution we&rsquo;re providing but they are no doubt a thorn in other developers&rsquo; sides. This is a follow up to a post I made about a month ago called <a href="http://actsasflinn.com/articles/2008/04/20/jsonp-on-rails-with-jquery">JSON-P on Rails with JQuery</a>. Below I&rsquo;ve laid out some of the Rails problems and solutions related to <strong class="keyword">JSON-P</strong>, <strong class="keyword">cross domain JSON using JSON-P</strong>, <strong class="keyword">JSON-P with jQuery</strong> and <strong class="keyword">Rails caching JSON-P</strong>.</p> <ol> <li><a href="#jsonp">JSON-P with Rails</a></li> <li><a href="#jsonpwithjquery">JSON-P with jQuery</a></li> <li><a href="#railscachingjsonp">Rails Caching JSON-P</a></li> <li><a href="#crossdomainjson">Cross Domain RESTful JSON-P</a></li> </ol> <h3>JSON-P with Rails<a name="jsonp">&nbsp;</a></h3> <p>My son: &ldquo;What are you doing?&rdquo;</p> <p>Me: &ldquo;Writing a blog post about JSON-P.&rdquo;</p> <p>My son: &ldquo;Who is Jason P.?&rdquo;</p> <p>Me: &ldquo;Javascript Object Notation with Padding.&rdquo;</p> <p>My son: &ldquo;Oh.&rdquo;</p> <p>So as you hopefully know JSON-P isn&rsquo;t some guy working in the back office of your IT department. JSON-P <u>is</u> a powerful data transport method in use all over the internet by some heavy hitters like Yahoo!, CNN, ESPN and lots more. JSON-P is a hack of sorts to get around a few problems like the dreaded <a href="http://en.wikipedia.org/wiki/Same_origin_policy">Same Origin Policy</a>. Plain old JSON is great but it can&rsquo;t do cross site/cross domain. <strong>Short of constructing a same origin proxy JSON-P is your best option for cross site AJAX</strong>. The best part about JSON-P is you can use it as an alternative to XMLHttpRequest to transport JSON data across sites.</p> <h4>JSON-P Structure</h4> <p>JSON-P can be expressed a number of ways:</p> <ol> <li>Embedded in an HTML request as an invisible iframe that includes a callback to instantiate JSON into the global scope. (clunky)</li> <li>With a static callback wrapping JSON (good for server cache, bad because of browser cache).</li> <li>With a dynamic callback wrapping JSON (harder to server cache).</li> </ol> <p>Out of the box Rails best supports option #3 like so.</p> <pre><code> render :json =&gt; @chats, :callback =&gt; params[:callback] </code></pre> <p>This could result in the following JSON-P response, <u>foo</u> being the callback param you submitted as part of your query string.</p></p> <pre><code> foo( {"chats": [ {"user": "actsasflinn", "created_on": "June 04, 2008", "id": 109328, "body": "Hey there Jim, I have never seen that kind of hat before!. Where did you get it?"}, {"user": "jim", "created_on": "June 04, 2008", "id": 109329, "body": "It's an ass hat. I got it from my ex."} ] } ) </code></pre> <h3>JSON-P with jQuery<a name="jsonpwithjquery">&nbsp</a></h3> <p>Using the above you can use some built-in <a href="http://jquery.com/">jQuery</a> methods to make life easy once again. In case you don&rsquo;t know, <strong>jQuery is the balls</strong>! jQuery&rsquo;s solution to the same origin policy is support for the <strong>script tag transport</strong>. jQuery will handle the transport magic if you specify a <em>callback=?</em> as a query param (yes question mark - jQuery fills it with a dynamic callback name in for you). This tells jQuery to add a dynamic callback and to use padding and the script tag transport. Check out the <a href="http://docs.jquery.com/Ajax/jQuery.getJSON">getJSON</a> method example using the dynamic callback query param.</p> <pre><code> $.getJSON("http://example.com/chats.json?callback=?", function(data){ $.each(data.chats, function(i,chat){ alert(chat.body); }); }); </code></pre> <h3>Rails Caching JSON-P<a name="railscachingjsonp">&nbsp;</a></h3> <p>The dynamic callback does a few important things like defeating the browser cache but it kills Rails&rsquo; ability to do the same. <u>Action caching the resulting JSON data doesn&rsquo;t work because jQuery changes the callback name with each request.</u> Overcoming the lack of caches_action isn&rsquo; t so bad as long you use data caching within your format.json block. The to_json method is pretty intensive and it&rsquo;ll kill your reqs/sec so it makes sense to cache the output from to_json. Using cache_fu something like the below will get you rolling with 500+ reqs/sec...</p> <pre><code> class Chat < ActiveRecord::Base acts_as_cached def self.recent_chats(format = nil) chats = find(:all, :order => "created_on desc", :limit => 10) chats.send(format) unless format.blank? end end class ChatsController < ApplicationController def index respond_to do |format| format.json do @json_chats = Chat.caches(:recent_chats, :with => :to_json) render :json => @json_chats, :callback => params[:callback] end end end end </code></pre> <p>It&rsquo;s not as great as action cache but it minimizes the db hit and the to_json processing time (which is hefty) reducing the response to simply padding the memcached JSON.</p> <h3>Cross Domain RESTful JSON-P<a name="crossdomainjson">&nbsp;</a></h3> <p>If you&rsquo;ve gone this far JSON-P is working wonders... unless of course you want to do AJAX POSTs (argh)! So this next bit of mojo is indeed a hack and not for the faint of heart. As you might know most browsers don&rsquo;t support the HTTP DELETE and PUT methods so Rails spoofs them by making an POST and passing in a query param called _method. Wonderful but you can&rsquo;t do an AJAX POST across domains. The AJAX REST Nazi says &ldquo;no REST for you!&rdquo; You can of course monkey patch Rails to use _method regardless of the actual HTTP method enabling you to spoof <strong>AJAX and REST across domains</strong>.</p> <pre><code> module ActionController class AbstractRequest def request_method @request_method ||= begin method = (parameters[:_method].blank? ? @env['REQUEST_METHOD'] : parameters[:_method].to_s).downcase if ACCEPTED_HTTP_METHODS.include?(method) method.to_sym else raise UnknownHttpMethod, "#{method}, accepted HTTP methods are #{ACCEPTED_HTTP_METHODS.to_a.to_sentence}" end end end end end </code></pre> <p>Achtung! Monkey patching with the above will expose your create method without using an actual post. Imho no big deal, others might be more cautious (<a href="http://actsasflinn.com/articles/2008/04/27/captcha-sucks">CAPTCHA</a> is always an option), ymmv. On to the controller...</p> <pre><code> class ChatsController < ApplicationController ... def create @chat = Chat.new(params[:chat]) respond_to do |format| if @chat.save format.json { render :json => { :chat => @chat }, :callback => params[:callback], :status => :created, :location => @chat } else format.json { render :json => { :errors => @chat.errors.full_messages }, :callback => params[:callback], :status => :unprocessable_entity } end end end end </code></pre> <p>Using jQuery to serialize your form, a spoofed AJAX POST might look something like this.</p> <pre><code> $(document).ready(function() { $('#chat_form').submit(function() { var chat = $('#chat_form').serializeArray(); $.getJSON("http://example.com/chats.json?_method=post&callback=?", chat, function(data){ if (data.errors == undefined) { alert(data.chat.body); } else { $.each(data.errors, function(error) { alert(error); }) } }); }); }); </code></pre> <p><strong>Huzah!</strong> Easy right? It took quite a while to put all this together into a cohesive process that everyone could work with. At the onset Rails didn&rsquo;t support spoofing REST, action caching JSON-P or even cross domain JSON but with a little ingenuity we made it happen and you can too. JSON-P is the solution to put your <strong>RESTful Cross Site XMLHttpRequest</strong> woes to bed.</p> <p>p.s. none of the above code has been tested so if you copy and paste it and it doesn&rsquo;t work, don&rsquo;t complain unless you include working code.</p> <p class="note">About Me: I&rsquo;m a developer with <a href="http://www.sportstechinc.com/">Sports Technologies</a>, a Rails firm specializing in community focused web applications aimed at sports and entertainment. We&rsquo;re always looking for Rails talent, if you&rsquo;re looking to work on rewarding high profile projects with a seasoned team of professionals give us a shout.</p> Fri, 13 Jun 2008 21:49:00 -0400 urn:uuid:e487fea3-aa51-4e4c-a9d1-a8a9e39a8544 http://www.actsasflinn.com/articles/2008/06/13/cross-domain-restful-json-p-with-rails#comments http://www.actsasflinn.com/trackbacks?article_id=cross-domain-restful-json-p-with-rails&day=13&month=06&year=2008 http://www.actsasflinn.com/articles/2008/06/13/cross-domain-restful-json-p-with-rails Passenger mod_rails - I'm a believer. <p>I was initially skeptical of <a href="http://modrails.com/">Passenger aka mod_rails</a> (because it seems to good to be true) but tonight I became a believer. We recently finished work on fairly high profile project. The installation seemed to be running fine but after installing monit regular tests revealed mongrel instances were hanging or unresponsive and randomly coming back online. After 3 days of the mysterious mongrel issues, apache tweaking of the proxy config, replacing mod_proxy_balancer with haproxy, and experimenting with other backends like thin and ebb I decided to give Passenger a shot. The gem was super easy and the apache install application was super easy and very helpful. After installing Passenger the new site is rocking. Goodbye mongrel.</p> Sun, 01 Jun 2008 02:55:00 -0400 urn:uuid:6643e530-061e-4f4c-8b07-7985e1769ec7 http://www.actsasflinn.com/articles/2008/06/01/passenger-mod_rails-im-a-believer#comments Rails ruby rails mod_rails passenger http://www.actsasflinn.com/trackbacks?article_id=passenger-mod_rails-im-a-believer&day=01&month=06&year=2008 http://www.actsasflinn.com/articles/2008/06/01/passenger-mod_rails-im-a-believer CAPTCHA Sucks <p>I was on Slashdot and there was actually something I cared to comment about&#8230; then I got this.</p> <p><img src="/files/wtf.jpg" alt="WTF Does This Say?" /></p> <p>Then I left.</p> Sun, 27 Apr 2008 17:59:00 -0400 urn:uuid:da1a23b8-dd08-429e-8782-1048d8c94077 http://www.actsasflinn.com/articles/2008/04/27/captcha-sucks#comments http://www.actsasflinn.com/trackbacks?article_id=captcha-sucks&day=27&month=04&year=2008 http://www.actsasflinn.com/articles/2008/04/27/captcha-sucks