ActiveRecord collection to_json fails

Really strange problem today, it appears that 1.1.3 has an issue. Upgrading to 1.1.4 fixed the problem.

>> Artist.all.to_json
ArgumentError: wrong number of arguments (2 for 1)
	from /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:300:in `to_json'
	from /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:300:in `json_transform'
	from /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:299:in `map'
	from /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:299:in `json_transform'
	from /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:272:in `to_json'
	from (irb):7

Adding a new Git remote repository

Remote server

rails@server:/repos$ mkdir project.git && cd project.git
rails@server:/repos/project.git$ git --bare init
Initialized empty Git repository in /repos/project.git/

Locally

rl@bloodandguts:~/project git remote add origin ssh://rails@server/repos/project.git
rl@bloodandguts:~/project$ git push origin master
Counting objects: 87, done.
Compressing objects: 100% (73/73), done.
Writing objects: 100% (87/87), 17.78 KiB, done.
Total 87 (delta 22), reused 0 (delta 0)
To ssh://rails@server/repos/project.git
 * [new branch]      master -> master

And finished.

Git submodules

Trying to add a new plugin which will be a submodule of a the main project I am working on.

cd ~/project
./script/generate plugin myplugin
mv vendor/plugins/myplugin ~/
cd ~/myplugin
git init; git add .; git commit -m "Plugin skeleton";
cd ~/project

# add the submodule to the project
git submodule add ~/myplugin vendor/plugins/myplugin

# initialise and pull the latest version of the plugin
git submodule init
git submodule update

# commit the added submodule config and the pointer to the current version
git commit ~/.gitmodules ~/vendor/plugins/myplugin

In order to remove a submodule you must

Delete the relevant line from the .gitmodules file.
Delete the relevant section from .git/config.
Run git rm --cached path_to_submodule (no trailing slash).
Commit and delete the now untracked submodule files.

sudo access with no password

If you need to enable sudo access on a remote server (or any machine for that matter) but really don’t want to have to enter your password everytime, you can disable the password prompting. I combine this with adding my public ssh key so I can just get on with things, and not have to remember a million and one passwords.

rob@mail:~$ sudo cat /etc/sudoers 
# /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#

# User privilege specification
root   ALL=(ALL) ALL
rails  ALL=(ALL) ALL
rob    ALL=(ALL) NOPASSWD: ALL

You can also fine grain this to disable the password prompt only for particular scripts if your user only really performs a few actions.

Day 2: differences between opensocial 0.7 and 0.8

In my playing yesterday I was trying to extract whether a viewing user had the app installed. The user attribute HAS_APP needed to be added to the request in order to return this, this caused some bother as it appears that HAS_APP is only available in opensocial 0.8 and the default on the MySpace platform is 0.7. However, upgrading to 0.8 required changing a few things.

opensocial.DataRequest.PersonId.OWNER;
opensocial.DataRequest.PersonId.VIEWER;

respectively become

opensocial.IdSpec.PersonId.OWNER;
opensocial.IdSpec.PersonId.VIEWER;

I then received the following error which hadn’t occured before.

data.get(opensocial.IdSpec.PersonId.OWNER) is undefined
[Break on this error] var owner = data.get(opensocial.IdSpec.PersonId.OWNER).getData();

It seems that request.add now takes two arguments, the second being a handle to extract the result from in the callback function.

dataReqObj = os.newDataRequest();
var viewerReq = os.newFetchPersonRequest(v);
//dataReqObj.add(viewerReq);
dataReqObj.add(viewerReq, 'viewer');
dataReqObj.send(viewerResponse);

function viewerResponse(data) {
//  var viewer = data.get(opensocial.IdSpec.PersonId.VIEWER).getData();
  var viewer = data.get('viewer').getData();
  heading = 'Hello, ' + viewer.getDisplayName();
  var has_app = viewer.getField(opensocial.Person.Field.HAS_APP);
  if (has_app) {
     heading += '<p>You have this app</p>';
  }
  document.getElementById('viewer').innerHTML = heading;
}

A detailed list of changes between 0.7 and 0.8 are listed here.

http://wiki.developer.myspace.com/index.php?title=OpenSocial_Version_0.8_Breaking_Changes

Day 1: First MySpace / OpenSocial app

Have been playing all day, not fruitlessly but not as much fruit as I would have liked with creating a MySpace profile app, this one should simply print the name of the user viewing the app, the name of the user who has the app installed and whether or not the viewer has the app installed within their profile. From there on the user should be able to be prompted to add the app for themselves. Although its not quite working I should be there in a few more hours.

<script type="text/javascript" src="http://api.msappspace.com/AppRendering/js/jquery-1.2.1.min.js"></script>

<style type="text/css">
  div#widget {
    width: 300px;
    background-color: #bee0ed;
  }
  div#widget img {
    margin: 14px;
  }
</style>
<div id="widget">
  <img src="http://devsite/layout/logo.png" alt="My Site" class="logo" />
  <div id="viewer">
  </div> 
  <div id="owner">
  </div> 

</div>

<script type="text/javascript">
 
var os;
var dataReqObj;
var dataReqObj2;
var heading = null;
var viewer = null;

var v = opensocial.IdSpec.PersonId.VIEWER;
var o = opensocial.IdSpec.PersonId.OWNER;

function init() {
    os = opensocial.Container.get();
    
    var params = {};
    params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.HAS_APP];

    dataReqObj = os.newDataRequest();
    var viewerReq = os.newFetchPersonRequest(v, params);
    dataReqObj.add(viewerReq);
    dataReqObj.send(viewerResponse);

    dataReqObj2 = os.newDataRequest();
    var viewerReq2 = os.newFetchPersonRequest(o);
    dataReqObj2.add(viewerReq2);
    dataReqObj2.send(ownerResponse);
}

function viewerResponse(data) {
    var viewer = data.get(v).getData();
    heading = 'Hello, ' + viewer.getDisplayName();
    var has_app = viewer.getField(opensocial.Person.Field.HAS_APP);
    heading += has_app;
    if (has_app) {
       heading += '<p>You have this app</p>';
    }
    document.getElementById('viewer').innerHTML = heading;
}

function ownerResponse(data) {
    var viewer = data.get(o).getData();
    heading = 'Hello, ' + viewer.getDisplayName();
    document.getElementById('owner').innerHTML = heading;
}

init();

</script>

ActiveRecord joinery blah

Hmmzzz, this one doesn’t cope with nil user_ids

users = User.find(UsersUsbLesson.find(:all, 
                                      :select => "distinct user_id",
                                      :conditions => "user_id > 0"
                                      ).collect(&:user_id))

much better, and uses a join instead of two queries to the db.

users = UsersUsbLesson.find(:all, 
                            :select => 'distinct user_id, updated_at',
                            :include => 'user'
                            ).map(&:user).compact

Firefox has lost my favour

I am sad to say that I am follow the trend of slamming down Firefox. In recent months I’ve found that I am using it less and less. I was initially turned onto it because of the tab support and the frustration of having multiple IE windows open for multiple pages. It just feels more natural and now IE feels painful and not pretty enough, Firefox’s default style just adds more to the page I guess and feels nicer.

Then I looked at plugins and now I have a Operator (for detecting microformats), Firebug, Web Development Toolbar, Elasticfox (for managing Amazon EC2 instances), FireFTP. They are all extremely useful and things I use daily.

However, Firefox is just becoming slower and slower and I am having to restart it at least twice a day, whether I am on Windows or Ubuntu. I am swaying over to Google Chrome as its just slicker and altogether faster little beastie. I am now finding that I am using Firefox for editing css with the Web Developer Toolbar, and debugging javascript with Firebug and that’s it, so I’m not actually using as a web browser as such anymore. Sad times.

Passenger announce support for Nginx

While I am not a huge fan of Nginx, largely because I can install configure Apache in far less time with little or no messing around, its good to see that Nginx support is on its way. My current client uses Nginx, Mongrel and Monit to run their Rails app. I’ve always disliked the flakiness of the set up, in fact the set up was similar with former clients too. Its a common deployment scenario and Passenger just does all the hard work for you.

http://blog.phusion.nl/2009/04/16/phusions-one-year-anniversary-gift-phusion-passenger-220/

capturing the exit status of a system call

Nice little snippet I came across today. The next time I execute a script I can establish the result without having to parse the stdout or stderr.

>> %x{echo "Hello World"}
=> "Hello World\n"
>> $?
=> #<Process::Status: pid=949,exited(0)>
>> $?.exitstatus
=> 0
>> %x{ /etc/init.d/apache2 restart }
(13)Permission denied: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs
=> " * Restarting web server apache2\n   ...fail!\n"
>> $?
=> #<Process::Status: pid=2016,exited(1)>
>> $?.exitstatus
=> 1