Custom ActiveRecord attribute serializers

Here’s an under-documented but extremely useful feature of ActiveRecord.

If you’re familiar with the serialize macro you’ll know that by default ActiveRecord will serialize the given attribute to YAML, and there’s no apparent way around it, but there actually is a way hidden in serialize’s implementation.

If you provide a second argument to serialize with the class you want the serialized attribute to belong to then ActiveRecord will check whether the given class responds to .dump and .load and use those methods to serialize/deserialize the object instead of the default YAML encoder. For this to work both methods need to be defined, defining just one won’t do.

So you could have, for instance:

class Recipe < ActiveRecord::Base
  serialize :ingredients, IngredientsList
end
 
class IngredientsList < Array
  def self.dump(ingredients)
    ingredients ? ingredients.join("\n") : nil
  end
 
  def self.load(ingredients)
    ingredients ? new(ingredients.split("\n")) : nil
  end
end

This is a very simplistic example (and probably not a very useful improvement over YAML serialization), but this method can become really useful when you want to use custom classes to define your serialized attribute’s logic, especially when those classes aren’t easily mappable to YAML.

Removing REST actions from an ActiveAdmin resource

If you’ve been using ActiveAdmin to manage your administration interfaces in Rails you might have come across the need to get rid of some of the default REST actions. Maybe your model is simple enough that it doesn’t need a “show” view, or perhaps you only want admins to be able to update user-generated content but not create it.

ActiveAdmin’s documentation doesn’t cover how to remove default REST actions, and so you might be tempted to simply replace the action links in your views to “hide” those actions, but that’s not a very pretty solution. Fortunately the API has a nice way of achieving this, you simply have to specify which actions you want using actions in the body of your admin definition, e.g.:

ActiveAdmin.register Moderation do 
  # Remove default REST actions except index, show and update
  actions :index, :show, :update
end

This actions method is actually a method of InheritedResources, a gem ActiveAdmin is built upon, and so it supports this other syntax:

ActiveAdmin.register Moderation do 
  # Remove create and show actions
  actions :all, :except => [:create, :show]
end

I hope you found this useful.

Kibo: a humble JavaScript library for handling keyboard events

Some time ago, after a certain amount of poking and prodding from my friends at quov.is (thanks, guys!), I finally released the first version of a little project I had been working on for a while: https://github.com/marquete/kibo – just what the title says.

I think everything is pretty much self-explanatory (Francisco got it working on one of his projects in a matter of seconds without asking me anything, so I guess that’s something). If not, drop me a line and I’ll do what I can. I’m a nice guy – I’ve helped people before.

There’s still room for improvement, or at the very least for new functionality (I’m looking at you, Mac users), but it’s already usable and I’ll continue to work on it when I can. I hope you’ll find it useful. Cheers!

Testing rendering of a partial and the case of the undefined `ref’

So today I was trying to test a controller which renders a partial in response to an XHR request:

context "when issuing an AJAX request" do
  before { request.stub(:xhr?).and_return(true) }
 
  it("renders just the comment") do
    post :create
    should render_template(:partial => 'comments/_comment')
  end
 
  # ...

But I kept getting the following cryptic error:

NoMethodError:
       undefined method `ref' for nil:NilClass

After scratching my head for several minutes I finally stumbled upon this blog post by Alejandro Riera Mainar, who had a similar problem, although not testing. His solution inspired me though, all I had to do was to specify the format in my mocked request:

  it("renders just the comment") do
    post :create, :format => 'html'
    # ...

And magically the test passed.

Global Game Jam 2012 @ quov.is

Finally… it’s Monday.

We’ve been together for 48 hours developing games for the Global Game Jam 2012 event and here you have the results!

Ourocytosis

Ourocytosis

Ourocytosis is the end result of several ideas we tossed together at the beginning of the Jam. All revolved around different interpretations of this year’s Theme. Some of us wanted to keep the idea of eating things and becoming what you eat. Others wanted to use the self-consumption theme to trick enemies into destroying themselves. Yet others strayed further from the path and suggested having the player live through several generations on a common setting.

Although we all liked these ideas, we had several concerns regarding the scope and time frame, so we went back to the drawing board. Although much of this concepts would carry on to our final project, there was plenty to be cut.

We continued to trim and cut and change opinions until we finally drafted the snippets that follow. I personally believe the beauty of this process is that ultimately none of the original ideas made it to the final cut. And all of us are happy with it =)

URL: http://globalgamejam.org/2012/ourocytosis

Last Flight of the USS Uriburu

uriburu
Three or more players control a crudely drawn super spaceship and shoot at other crudely drawn things. In space.

URL: http://globalgamejam.org/2012/last-flight-uss-uriburu

We hope you enjoy these games and come back soon for more!

Setting up the Facebook JavaScript SDK channel file the easy way with Rails

If you’ve used the Facebook JavaScript SDK you probably know about the “channel file” that Facebook recommends setting up in your server.

The docs stress the importance of setting proper cache headers in the server’s response, which means we can’t just drop the file as a static file under public/. Luckily for us we can take advantage of Rails 3′s router, which allows routing paths to Rack applications. The contents of the channel file are very small, just a <script> include tag, so we can simply inline a Rack app that returns those contents with the right headers, and we’ll be done.

Facebook provides this example in PHP:

<?php
$cache_expire = 60*60*24*365;
header("Pragma: public");
header("Cache-Control: max-age=".$cache_expire);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$cache_expire) . ' GMT');
?>
<script src="//connect.facebook.net/en_US/all.js"></script>

So let’s translate that into a Rack app using a Proc and putting it in config/routes.rb:

# config/routes.rb
get '/channel.html' => proc {
  [
    200,
    {
      'Pragma'        => 'public',
      'Cache-Control' => "max-age=#{1.year.to_i}",
      'Expires'       => 1.year.from_now.to_s(:rfc822),
      'Content-Type'  => 'text/html'
    },
    ['<script type="text/javascript" src="//connect.facebook.net/en_US/all.js"></script>']
  ]
}

If you think that code looks too ugly to be in your routes file you can always move it over to a module and put it in your lib/ folder, just make sure to define self.call as the entry point for the Rack app.

To test that it works we can run the Rails server and make a request using curl:

[pilaf@bmo ~]$ curl -i 0.0.0.0:3000/channel.html
HTTP/1.1 200 OK
Pragma: public
Cache-Control: max-age=31557600
Expires: Thu, 24 Jan 2013 00:30:15 +0000
Content-Type: text/html
X-UA-Compatible: IE=Edge
ETag: "5ee12707f54a4af13db5808826dd8040"
X-Runtime: 0.001898
Content-Length: 59
Connection: keep-alive
Server: thin 1.3.1 codename Triple Espresso

<script src="//connect.facebook.net/en_US/all.js"></script>

There, all headers are showing up, as well as the contents of the file.
Hope you found that useful.

Update: s/from.now/from_now/ (thanks to Ben, Martin and Peter for noticing it)

Global Game Jam 2012

quov.is is happy to announce that it will be a host for the Global Game Jam 2012 in Buenos Aires.

We’ll be gathering from Friday 27th to Sunday 29th (January) to make teams and develop one game per team.

If you want to learn more about the Global Game Jam head to http://globalgamejam.org

If you want to join us please send an email to info@quov.is and we’ll answer with guidelines on how to register.

 

Old-fashioned Rangers vs. Scrum Club

This story is about two soccer teams. One was called Old-fashioned Rangers and the other one was called Scrum Club. These two teams were based on the same city, but they were very different. Old-fashioned Rangers started their day early for training. The players arrived at the club and began to run and follow orders from the team captain. They were all good players and good boys, but they didn’t know each other very well. This was so uncomfortable that once in the middle of a match, one of the team wings was asking for the ball, very near to the goal, screaming “Mike! Mike! Here!! Come on!!”… of course the player with the ball passed it to another player and the team couldn’t score. His name was Matthew.

Every morning they practiced the same things and followed the captain’s strategies. This was a big problem because when they played tournaments, the other team always knew what they were going to do, and the worst thing was that the coach was always surprised about this, because he never checked the progress of the team at the end of each week.

One afternoon Mitch Andrews, the goal-keeper of the team, took off his uniform and said “It’s over, I’m done. I can’t take this anymore, I’m tired of Randy and William, they are too lazy and we are going to keep losing matches”. It was a pity. Maybe if he had said it after one of their weekly training sessions, they could have found a solution and wouldn’t need to go away at the end of the season. So, this was Old-fashioned Rangers, a team with great players but bad results.

On the other side of town, Scrum Club had similar players, but they did things a little differently. Each morning the players arrived at the club and before training they had a short talk about what was going on with the team and the tournament, what each one of them had been doing the day before and what they were interested in practicing that day, new training ideas, etc. Of course, they knew each other very well and some of them were friends. Their captain was a good leader, but he didn’t think of himself as better than anyone else on the team. He always tried to keep things well-organized. That was why everyone arrived on time to each training day, not because they were just following orders, but because they were happy to be there.

Once a week, before going home to their families, the members of Scrum Club talked about their concerns and the good and bad things that happened during the week. By doing so, they became aware of their shortcomings as players and were able to work on fixing any problems that arose among them. I remember one afternoon when Jeremy Linus was having some trouble practicing penalty kicks. He was very upset about it and said “I am the worst player ever”. That day Michael and Jack helped him find his problem – they realized it was time to change his shoes. He never missed a penalty again.

So, this was Scrum Club, a team whose coach always kept track of the team’s progress, building charts and improving the training process every day.

On February 2009, these two teams faced off in the finals. I don’t need to say who won the match.

Did you know #1: Underscores in Ruby numbers

Did you know that you can add underscores between digits in Ruby and the interpreter will gently parse them as numbers? This is nice to represent thousands!

The only limitation is that you can’t start a number with an underscore.

  # Valid Number
  1_000 # => 1000
 
  # Not valid
  _1_000 # => NameError: undefined local variable or method `_1000' for main:Object

Enjoy!