JSON-P on Rails with JQuery

Posted by acts_as_flinn Sun, 20 Apr 2008 17:22:00 GMT

JSON-P based Comment

Over the last several months I’ve had the pleasure of developer JSON based commenting solutions for publishers. I couldn’t be happier using JSON as a transfer method for moving ActiveRecord based object from the database almost directly to the consumer. I’ve run into some difficulties here and there mainly due to the Same Origin Policy which is a bastard of a browser rule that makes sending JSON across domains difficult. Even though prototype.js seems to support sending requests across domains there is no native script transport in prototype and worse yet it appear some browsers won’t allow AJAX across subdomains to overcome the SOP rules. I searched all over the web and found a few hacks for adding the script tag to prototype.js but I found the best solution was built native into JQuery’s getJSON. I was really taken with JQuery’s ability to handle the script transport method out of the box but I think even more I’m taken with JQuery’s syntax. I had a conversation with Less Everything’s Steven Bristol about 6 months ago and he asked if I had checked out JQuery. I had briefly looked at it but I wasn’t wowed by it (probably because I didn’t use it on a project). Steven: “isn’t it the best thing you’ve ever seen?” Me: It’s ok. (*my answer to everything – ask my wife). Six months later I get to use it on a project and my answer to you Steven is YES it is the greatest.

JSON-P

Back to the subject… So the problem is that a browser doesn’t want to send a request across domains for fear that your secret info will be compromised by some would be hacker. The solution JSON padded with a callback method combined with a plain old script tag aka JSON-P. With JQuery the idea is that you can pass a URL into JQuery’s getJSON method with a ? for JQuery to bind it’s on changing function name that handles a callback. Sound like a hack? Yes but everyone is doing it. I’ve seen some skeptics but overall this is an accepted solution. And until JSONRequest is accepted as a safe cross site transport JSON-P is here to stay.

Does Rails support JSON-P?

Bet your ass it does. Right out of the box Rails supports the callback option to be passed in on a :json render. Like so:

render :json => @comments, :callback => params[:callback]

JSON-P Problems on Rails

So the issue you’ll run into primarily with JQuery is the changing name of the callback. JQuery binds a random function name to the request (presumably to protect from attacks of some sort, maybe for anti caching). The issue is that with action caching caches the entire response body meaning the next call has a stale cache (because of the now changed callback name) or has to generate a new response for a new callback name. While JSON is typically very light weight the to_json method can be expensive and when you’re dealing with high traffic situations you always want to squeeze every bit of performance out that you can. We also do paginated result sets with will_paginate so it means there is a bit of post processing after a plain old find_all_by_blah… The solution I’ve been using is a mix of cache_fu for model level caching along with fragment caching the to_json results then interpolating the cached json into the callback. Sound like a hack? It is but it feels a bit better when you crunch out over 500/reqs/s as opposed to 14/reqs/s.

For the future

Let’s cross our fingers for CouchDB. I’ve been experimenting with Couch over the last week or two and I’m really pleased with the possibility of a RESTful document based database with native JSON and coming support for MapReduce. The future looks bright, I can imagine not so distant support for native ruby object level persistence. Yay!

Rails Deployments Tips

Posted by acts_as_flinn Wed, 16 Jan 2008 15:04:00 GMT

Very often when projects go into production there are a few tweaks needed to make sure the app works correctly in its production environment and stays working. Below are some tips I’ve come up with from my experience rolling rails apps. Most of them are no brainers and some probably apply only to the Rails development we’re doing at work.

Rotate Rails Log Files

Log files get big really quick on high traffic sites. Some server apps rely on the operating system or a log rotating script to archive or delete old logs. Rails has a built in feature thanks to Ruby’s Logger class. The following code will keep 50 archived logs each 1mb in size and automatically rotate the log out once it hits 1mb.

In conf/environments.rb


Rails::Initializer.run do |config|
  # ...
  config.logger = Logger.new(File.join(RAILS_ROOT, 'log', "#{RAILS_ENV}.log"), 50, 1.megabyte)

Ignore Sensitive Parameters in Logs

Sick of seeing your bank password showing up in your Rails based shiny new web 2.0 app? Yeah I know don’t use your bank password but hey if you’ve done it users of your shiny new web 2.0 app probably will too. Keep them safe by keeping their passwords out of your logs. The following hides the password and password_confirmation params from your logs.

In conf/environments.rb


# Include your application configuration below
ActionController::Base.filter_parameter_logging :password, :password_confirmation

Robots.txt

If you have a development site that isn’t password protected to the public for whatever reason you’ll want to make sure the development site isn’t getting indexed by search engines and cluttering up results for your production site.

Create a file called robots-development.txt and on your development site use mod_rewrite to point to the file.


User-agent: *
Disallow: /

Password Protect Mod Proxy

So this goes along with the last topic. If you’re using password protection along with mod proxy you’ll notice that your assets are password protected but page requests still make it to mongrel. Painful on your search results if msn, yahoo or googlebot come to visit.


<Proxy balancer://mongrel_cluster>
    AuthName "Keep Out" 
    AuthType Basic
    AuthUserFile htpasswd.users
    Require valid-user

    BalancerMember http://192.168.1.2:8000
    #...

Turn on /etc/init.d scripts!

This seems like a no-brainer but if you installed apache from source and/or you are using mongrel cluster you’re doing this manually.

Copy the script from the mongrel_cluster resource directory to /etc/init.d


# cp /usr/local/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster /etc/init.d/mongrel_cluster
# chmod +x /etc/init.d/mongrel_cluster

On Redhat


# chkconfig --level 345 httpd on
# chkconfig --level 345 mongrel_cluster on
On Debian

# update-rc.d httpd defaults
# update-rc.d mongrel_cluster defaults

More to come…

Derek Sivers Blaims Rails for Project Mismanagement

Posted by acts_as_flinn Sun, 23 Sep 2007 15:01:00 GMT

Some of you might have seen the O’Reilly article by former Rails trumpeter Derek Sivers entitled 7 reasons I switched back to PHP. Or the Slashdot article, even more ominously named Thinking about Rails? Think Again. In typical fashion, Slashdot ran the link with a suggestive name which I’m sure will effect the credibility of Rails in the eyes of the uninitiated masses of PHP developers trolling the website.

I happened to read the article earlier in the morning before it made it to Slashdot and didn’t think too much of the arguments behind the article. I can honestly say from my own experiences that mismanagement of a project, not limitations of a framework or language are usually to blame for missed deadlines, and project failures. I can say that from experience after developing the same project in both PHP and Rails with about 1/3 of the tables (and probably logic).

Anyone with a lick of common sense can tell you that if you’ve got a legacy application with 90 tables, migrating that data and accompanying application to an MVC framework is going to be a big project. With a 2 person team, 1 of which is the owner of the company (who should be focusing on more important things), the project is going to take a long time, cost a lot of money and the likelihood of failure is high.

I think Derek’s logic and motivations for pursuing the project should be at question, not his choice of programming language or framework. Why do companies go into business? To make money of course. What possible reason does a company then have to rebuild it’s entire infrastructure from the ground up? To either make more money, or save money ie. make more money. The 7 reasons he switched back should have coincided with business considerations before he started the project not after the project failed. I think it’s shameful to place the blame of the project’s failure on the language and framework choice.

I’d love to hear what bitsweat honestly has to say about the project but we can be sure either an NDA or professional courtesy will keep that from coming out.

The comments at the end of the article do this opinionated scapegoat of an article justice.

Useless post without a concrete illustration.

Show us an example of:
1) What you tried to accomplish.
2) How you tried to implement it in rails.
3) The rails code that "didn't work." 
4) The "beautiful" PHP code you created instead.
Richard Hertz | September 22, 2007 08:03 PM

I especially like this one:

I'm a little reluctant to add to the wasteland that is this post and these comments, but here goes.

I'm familiar with the situation here. The deal was this: Derek was not a programmer; he was a musician. He learned some PHP and cobbled together the old CDBaby site by himself. It was good.

Then, he heard about Rails, and became infatuated with it. He proceeded to attempt a rolling rewrite of CDBaby's frontend and backend both (the backend is large, because of inter-label and digital distribution stuff) in Rails.

At this time, Derek had no experience with the following things:

* any language other than PHP
* systems integration and interoperability
* Rails
* object-orientation
* the MVC pattern
* managing a development team

Project fails. All right. As he has learned in #2, legacy compatibility trumps everything. Also, ship early and often.

As you can see in Derek's post about MySQL encodings, he's not always the clearest thinker. Even above he says that REST means POST-only destruction, which misses the point entirely.

His team was fine (mostly just Jeremy, until another developer was hired in the last months). Rails was fine. But there were a lot of things wrong with the project plan ("rewrite everything, eventually") and with the project leader, who was convinced he had found a silver bullet.

No framework saves you from your own inexperience.

Out.
wellwisher | September 23, 2007 01:47 AM 

Older posts: 1 2 3 ... 10