LazyGenerate: How to lazily generate properties in ActiveRecord

At times in the Posterous days we wanted to add new properties but a migration would be prohibitively expensive given a large corpus of data.

Here's a simple module you can include in your ActiveRecord objects to do just that — lazily generate potentially costly computation and save it to an object only when it is actually called. 

Dragons in these hills — but sometimes you want that. We're going to steer clear of these kinds of hacks for Posthaven, but as a minor exercise in metaprogramming maybe this'll be useful in the future:

One of my favorite additions to Rails 3 - ActiveRecord::Store - brings sexy back to old unsexy MySQL

One of the least favorite things I hated to do was migrate schema. Luckily Rails 3 has this new semantic called 'store' -- as detailed here

Store gives you a thin wrapper around serialize for the purpose of storing hashes in a single column. It's like a simple key/value store backed into your record when you don't care about being able to query that store outside the context of a single record.

You can then declare accessors to this store that are then accessible just like any other attribute of the model. This is very helpful for easily exposing store keys to a form or elsewhere that’s already built around just accessing attributes on the model.

Make sure that you declare the database column used for the serialized store as a text, so there’s plenty of room.

Examples:

class User < ActiveRecord::Base
  store :settings, accessors: [ :color, :homepage ]
end

u = User.new(color: 'black', homepage: '37signals.com')
u.color                          # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor

# Add additional accessors to an existing store through store_accessor
class SuperUser < User
  store_accessor :settings, :privileges, :servants
end

I love this because now I can just store extra info at any time just by altering my model code. No more waiting for the next schema migration and all the pain of that on a production server. Just drop it into a serialized hash that's persisted into a TEXT blob on your row, and you're all good. NICE. 

Of course that doesn't solve the problem of needing to index something specific -- but you can always just add that in your next major schema revision anyway, and then fill in that column on an offline basis later. 

Back in 2010, Adam D'angelo speculated that NoSQL was mainly a fad that would end with a relational database with more relaxed semantics. Well, this is at least 50% of the way there, at the app level.

Hell, this is actually how FriendFeed would store data in MySQL back in the day -- JSON blobs, and they'd just create new tables when they needed new indices. No schema changes EVER with that approach. 

Little things like this make it difficult to impossible for me to consider using other web platforms than Rails -- other than years of my tooling about in it (and learning all kinds of lessons the hard way), things just keep getting better and better. 

OmniAuth 1.0: How to do Google/Twitter/Facebook login right in Rails (new railscast)

Things are much much much improved from before. Of particular note is how much cleaner the Oauth2 API's are.

OmniAuth recently reached version 1.0 and has a number of nice additions. In this episode we’ll take a look at a new strategy called OmniAuth Identity which allows users to create an account by supplying a user name and password instead of logging in through an external provider.
Watch and read the awesome tutorial at railscasts.com

 

Trying to install rvm and you're getting an error "usage: dirname path"? Here's the fix

So my home directory is on my secondary volume, so it's actually at /Volumes/Secondary HD/Users/me -- unfortunately the RVM install script when you run "bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)" will output this annoying error "usage: dirname path". It's maddening. I checked the chat logs and Google didn't come up with a fix. 

Luckily I busted out my bash-fu to debug the RVM install script. Pro tip -- run bash -x scriptname.sh and it will give you the line number things fail on. I saw that it was failing on line 318. A little digging and I noticed that what was happening was since my directory name has a space, it was borking one of the commands.

So you came here for a fix right? Here's the simple fix.

  1. EDIT: Oops, it looks like RVM doesn't support home directories with spaces in them at all. 

According to RVM docs though, you can install as root (run sudo bash to get a root shell)  and it will install to /usr/local -- so even though that's not the recommended way to do it for dev users, this seems to be the best way to get it to work if you have a space in your home directory. (As of 2013 this is how you do a "multi user" install, which works just fine.)

Google's 174 web fonts in one convenient downloadable tarball for your Photoshopping enjoyment

Google’s Font Directory and API for web fonts could have a transformative effect on how we read the web. The only problem is, Google has made it very difficult to download all of the actual font files.

Web designers must be free to experiment with these new fonts, to sketch, comp and get to know these typefaces in browser and non-browser applications. This is why I’m providing this archive. 

Download Google’s Web Fonts
38.9 MB on disk (38,869,231 bytes)*
Updated 2011-03-15

You can use it in web pages, but until I found this, I couldn't design with it. Now I can. EPIC WIN.

I found the packaging still vaguely annoying since each ttf file was in a separate directory, so I ran this on the command line (cd to the untarballed directory first):

mkdir all; find . -iname '*.ttf' -exec cp \{\} ./all \;

Then I had all the ttf files in one directory at the root (./all) and I could drag and drop that into OS X fontbook.

Node.js beginner links

This is the minimal list of links that I think you need to get up and running with node, express, and a fully functioning node site.

Node.js homepage
This is the beginning. Node.js actually runs your javascript file. It's the interpreter runtime. 

Express.js
Express gives you Sinatra-like routing. It gives you the baseline to be able to run a functioning web app.

Mongoose ORM
Mongoose gives you pretty syntax for accessing MongoDB models. It can be your data layer. 

Jade
The default HAML-like template format for express 

NPM
it's a package manager like gem or CPAN for the node universe -- install, compile, update all from one command line. 

NPM module listing
listings of useful NPM projects, super useful.


Tutorials

How to Node.org
Great up-to-date blog, thanks for the suggestion @DShankar!

Nodepad: An in-depth tutorial
How to write a full app, In 15 parts...


For Rubyists

Node JS for my tiny ruby brain
via technoweenie of github


Advanced Topics

socket.io - easy realtime long polling library

coffeescript - beautiful syntax for javascript -- you can write an entire node project in coffeescript. Worth +10,000 elegant hacker points.

Node Inspector - debugging for your server

nvm - node version manager, kind of like rvm but for node -- cleanly lets you switch between node.js interpreter versions