Blog http://blog.siyelo.com Most recent posts at Blog posterous.com Fri, 30 Dec 2011 02:41:00 -0800 Intro to Machine Learning in Ruby http://blog.siyelo.com/machine-learning-in-ruby-statistic-classifica http://blog.siyelo.com/machine-learning-in-ruby-statistic-classifica

Machine learning is branch of Artificial Intelligence (AI) concerned with design and development of algorithms that allow computers to learn. It's a very broad subject so we will just focus on a simple example that uses statistical classification.

 

Let's build...

 

In this tutorial we are going to build a simple news classification application that will parse and classify RSS/HTML articles from the Times Live newspaper.

For the job, we will use nokogiri gem and 2 ruby standard libraries: open-uri and rss/2.0.

RSS Parser

To find sources of articles for processing,  we could build a complex search engine or we can simply use the RSS feeds the newspaper provides us with to look for and discover links. RssParser class does exactly that, you initialize it with a feed url and it gives you back the links to all the articles discovered in that feed.

HTML Parser

Having article links, we need to parse page content and extract meaningful parts from these pages. HtmlParser class can be initialized with a page url and DOM selector. In this example we will be using a CSS selector to extract the content from articles - Firebug and jQuery were used to find the selector for the text we are extracting from the article. In this class you will also notice clean_whitespace method which cleans the whitespace characters from the extracted text.

Statistical Classifier

We introduce a class that is responsible for classification of articles. It is initialized with a hash that consists of categories (keys) and training data (values).

Training data is used to discover potential relationships between articles and categories. This data should be carefully selected in order to give better classification results. It is created by determining the value for each word in the context of all words for that category (see the train_data() method).

In this example we are using content of Wikipedia articles for economy, sport and health as training data for our categories.

When classifying articles we want to compare only meaningful words and ignore other words that do not add any value for a certain category. We (partially) solve this problem using stop words.

Finally, the scores() method creates the scores for each category (per text) that we are testing.

Lets have a go

Here is the script that runs the program:

Although our statistical classification algorithm is very simple, it can give remarkably good results provided the training data is good. For even better results you can try other classification algorithms like Bayesian probability and Latent Semantic Analysis.

If you are interested in a more indepth example of a news aggregator application - you can check newsagg at Github. It's a simple Sinatra application with a Redis datastore that we put together. It crawls, classifies and creates 'clusters' of articles using statistical algorithms.

If you want to learn more about Machine Learning, checkout Programming Collective Intelligence book - code examples written in Python and Scripting Intelligence - code examples written in Ruby.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1595979/dalibor.nasevic.jpg http://posterous.com/users/hdKy9bKyhIb5U Dalibor Nasevic dalibor Dalibor Nasevic
Wed, 28 Dec 2011 13:01:00 -0800 Redis in the NoSQL ecosystem http://blog.siyelo.com/redis-in-the-nosql-ecosystem http://blog.siyelo.com/redis-in-the-nosql-ecosystem

Redis (REmote DIctionary Server) is key-value in-memory database storage that also supports disk storage for persistence. It supports several data types: Strings, Hashes, Lists, Sets and Sorted Sets; implements publish/subscribe messaging paradigm and has transactions.

All these different options place Redis in the NoSQL ecosystem somewhere between simple caching systems like memcache and feature-heavy document databases like MongoDB and CouchDB. The question is: when do you pick Redis over other NoSQL systems?

Give us some ACID

Before going into the use-cases, let's say one more important thing about Redis. Redis is single threaded which allows it to be ACID compliant (Atomicity, Consistency, Isolation and Durability). Other NoSQL databases generally don't provide ACID compliance, or they provide it partially. By default Redis trades some durability in return for speed (default fsync() is set to everysec which means it will save data to disk every second). But, because Redis is very configurable, you can change how many times it will fsync() the data on disk by using the appendfsync command (you can use appendfsync always and system will fsync data after every write - it's slow but safest!).

When to use Redis?

In your production environment you don't need to switch to Redis. You can just use it for the new things you are implementing. Always pick right tool for the job. For stable, predictable and relational data pick relational database. For temporary, highly dynamic data pick NoSQL database; schema changes can be a big problem and can take forever in big relational databases.

If you have a highly dynamic data that changes often, storage tends to grow quickly and further involves schema adjusting to store them, then Redis can be a potential good choice.

If you need a more featured document oriented database that allows you to perform range queries, regular expression searches, indexing, and MapReduce you should check MongoDB, CouchDB or similar. If you need a simple caching with better expiration algorhitms than Redis has then you should check memcache.

Redis Use-Cases

  • Access Logger: When you need to log different activities, Redis is a good solution. Because Redis has to keep all stored objects in memory, don't forget to archive data to relational/document database because it can grow quickly after some time.
  • Counting Downloads: Rubygems uses Redis for counting downloads of gems. See how it's implemented in the Download model.
  • High Score tables: Redis supports data type functions that can be very handy.
  • Who's Online: Use Redis to implement who is online logic in your application.
  • Caching: Finding followings, followers or similar is very expensive operation in relational databases, use Redis to cache these data.
  • Queues: Resque is a Redis-backed Ruby library for creating background jobs, placing them on multiple queues, and processing them later.
  • Live debugging: You need to do live debugging or roll out new features for production testing for specific users only - Rollout gem does exactly that.
  • HN style social news site written in Ruby/Sinatra/Redis/jQuery - lamernews.

Play with Redis (install, start and stop server)

Redis console

You can use redis-cli to connect to a local or remote Redis server and call com-
mands. Here is an example (first connect to the server using: redis-cli -p 6379):

Redis from Ruby

Here is an example using Ruby to execute commands on Redis server. You need to install redis gem by executing gem install redis first.

Learn more about Redis commands and give some speed to your web applications for free.

Real world Redis example

At the end, lets show a real world example how Redis is used in Rubygems for caching gem downloads count. For keeping the code snippet short some code is ommited and/or simplified.

First, in the initializer a new redis object as a global variable $redis is instantiated. This object is used in Download model for updating the downloads count for a gem with self.incr(name) method and reading the downloads count for a gem with self.for_rubygem(name) method. Rubygems is using Sinatra application Hostess to speed up gem downloads. Sinatra application is registered as a middleware in the application.rb config file. This application defines get "/gems/*.gem" route which triggers the downloads count to be updated in the Redis database.

Rubygems is doing more download stats like: total downloads, downloads per gem, downloads for a specific gem version, etc. Check out the source code at Github for more details.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1595979/dalibor.nasevic.jpg http://posterous.com/users/hdKy9bKyhIb5U Dalibor Nasevic dalibor Dalibor Nasevic
Wed, 14 Dec 2011 01:51:00 -0800 jQuery Mobile overview http://blog.siyelo.com/jquery-mobile-overview http://blog.siyelo.com/jquery-mobile-overview

We've all heard it, the browser is the future for the mobile applications. Mobile web frameworks are getting a lot of traction lately. Is this the turning point where these frameworks will finally set the developers free from the walled garden model of the Apple App Store and the complexity and resources needed for developing and maintaining a separate code base for each platform out there?

It's been almost a month since the 1.0 stable release of jQuery Mobile, the touch optimized mobile web framework. Only a year after John Resig announced the project in its first alpha stage, the jQuery team managed to deliver a solid release with an impressive graded support for a wide range of mobile browsers and platforms.

Built upon the jQuery core and the jQuery UI, the framework aims to deliver a quick and easy way to build unified cross-platform HTML5 based user interfaces with a single code base. All you need to start building applications using the framework is knowledge of some JavaScript and some HTML5.

Building a mobile application with jQuery Mobile is extremely easy and fast

One of the biggest advantages of jQuery Mobile is that even as a newcomer to the framework you can develop a rough version of your application in a matter of days as opposed to the native application development for Android and iOS where the learning curve is not quite as steep.

To make your application mobile just include the jQuery Mobile files in your header

Add the data attributes to your HTML markup

And this is the result:

34522551610-orig

The framework takes care of applying the styles and positioning the elements to fit and scale nicely on any device. With just a couple of html lines we have a template for our mobile application. Off course you can add your custom css styles to tweak the looks to your desires. Also with the release of the 1.0 support for the ThemeRoller tool has been added, so quickly theming your application is a breeze.

The important part in the html snippet above are the HTML5 data-* attributes. The framework relies on these data attributes in order to do it's magic. Older browser will ignore this attributes and just render the regular html. Basically the layout of a jQuery Mobile application is defined by the data-role attribute. In the above example we can see that we have a divs with data-roles "header", "content" and "footer" all of which belong to the main page wrapper. Also we added a data-role on the list element in order for the framework to “widgetize” it.

By default, linking to other pages is automatically done via Ajax in a single-page model. All you need to do is define a standard links and the framework will take care of it. If the device doesn't support Ajax for some reason the framework falls back to standard http requests. Another cool feature of the framework is linking within a multi-page document. A single page can contain many page containers defined by the data-role of “page” which means immediate display of the clicked page. When using this techniques combined with the page transition effects, the user experience feels almost “native app” like.

Web vs Native

Currently the biggest argument being used against the wider adoption of the mobile web applications is the limited access to the client device features. A common example to address this issue is combining the framework with tools like PhoneGap and delivering the application as native. Combining the framework with tools like PhoneGap also minimizes the lower performance issues since all of the resources can be loaded from the device.

Hopefully we will see a quick adoption of the proposed WebAPI specifications by Mozilla that define a standard of APIs that would give the browser high level access to the device components like GPS api, filesystem api, accelerometer api, dialer, messaging etc.

Conclusion

While all of those features provided by the jQuery Mobile framework are really cool and exciting, does the framework really provides a mature native-like feel and functionality to the applications built with it?

The jQuery team have done a great job by providing a nicely packed framework with lots of features like progressive enhancement approach, theming framework, unified widgets, modular design, a great cross-browser compatibility, even for older and less capable browsers and devices. But there is much left to be desired in the performance area. Even when trying the simple examples on a high end devices the page transition effects and the general user flow feels a little clunky. This is the area that jQuery Mobile fails short when compared to the native applications and even other Mobile Application frameworks (jQTouch or Sencha) but it probably be fixed in near future with the polishing of the rough edges.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1696014/naum.jpg http://posterous.com/users/cPRhSHKFW67Ue Naum Kostovski naumkostovski Naum Kostovski
Tue, 13 Dec 2011 10:07:14 -0800 Stop Internet Censorship - FIGHT SOPA http://blog.siyelo.com/stop-internet-censorship-fight-sopa http://blog.siyelo.com/stop-internet-censorship-fight-sopa We've censored the following, in protest of a bill that gives any corporation and the US government the power to censor the internet--a bill that could pass THIS WEEK.
A █████ ████ of █████████ █████ ███████████ ███████ the ████████: █████, ████, █████ █████, █████, █████ ██████ and ████, ███████. ██████ we act now. █████ ████.

To see the uncensored text, and to stop internet censorship, visit:http://americancensorship.org/posts/4672/uncensor

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Mon, 12 Dec 2011 01:53:00 -0800 Siyelos' git workflow http://blog.siyelo.com/siyelos-git-workflow-58876 http://blog.siyelo.com/siyelos-git-workflow-58876

Here at Siyelo we have a rather robust flow that we feel works quite well. This didn't come easily. It took lots of experimentation until we found out what exactly works for us. In this post I’m going to give a brief outline of how we work:
 

Named Branches

We rarely work on dev/master. Almost every feature we work on will get it’s own branch. Each branch will be pushed up to github in their own namepace (to prevent cluttering).

Pull Requests

When a branch is ready to be merged into dev we like to squash all the commits in that branch. This makes it easier for people reviewing the branch to get an overview of what is being done, it also makes for a cleaner git log.

We do, however, avoid squashing commits in the even changes are requested after the branch has been reviewed. We find this helps with the review process as it is easier for the reviewers to digest.

Why pull requests?

Pull requests serve 2 functions:

Firstly they give a very transparent overview of what is being worked on and what is ready to be merged and deployed.

This is also a great way to have your code peer reviewed. Github allows collaborators to comment directly on a line of code or on an entire commit or feature.

Merging

Once a branch has been given the go-ahead and the CI passes, one of the reviewers will merge the branch into dev. This is partly so there is a shared responsibility of the code in the repository and so there is always more than one person who understands that feature.

Deploying

Once merged in, the branch is immediately deployed to staging.

Deploying immediately will reduce big merges (merges will be easier) and we are able to gain visibility of bugs as they are introduced.  It also gives us more time to locate possible defects, if any.

If you're looking for something more specific, don't hesitate to ask :)

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1696150/me.jpeg http://posterous.com/users/ejjcB09K0psRc Peter Garbers petersiyelo Peter Garbers
Thu, 08 Dec 2011 00:04:32 -0800 We have a new phone number! http://blog.siyelo.com/we-have-a-new-phone-number http://blog.siyelo.com/we-have-a-new-phone-number
Siyelo has changed its Cape Town office number to  +27 (0) 21 461 2050.

Our old landline number (+27 21 461 2559) was previously registered to the Dept of Home Affairs, and was still listed on their website, so we were getting several nuisance calls a day from irate visa applicants;

"Good morning, Siyelo Software, Glenn speaking"
"Hi, my boyfriend is having problems with his visa application..."
*facepalm*

We decided it was easier to deal with the notorious Telkom than it was to ask Home Affairs to update their website. Talk about having to choose the lesser of two evils!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Thu, 03 Nov 2011 01:37:00 -0700 Remote pair-programming with Screen http://blog.siyelo.com/remote-pair-programming-with-screen http://blog.siyelo.com/remote-pair-programming-with-screen

At Siyelo we have 2 distributed teams, one in Cape Town and another one in Skopje. Naturally, we had to figure out how to do remote pair programming between the two offices. There are different available options for remote pair-programming (a great summary post available here).

In the past, we often used Skype for screen sharing, but the problems with Skype are:

  • you don't have control over the other screen
  • you cannot have both screen sharing and video
  • bandwidth of the internet connection sometimes can be a problem
  • it's not a tool for pair programming

Recently we have been experimenting with Google+ hangouts and although it has the same limitations, we prefer it over Skype for audio/video communication. But, what we really want from a remote pair-programming tool is the ability to do real time code collaboration.

The solution: screen. Screen can have many useful scenarios, but here I will focus on following two:

  • read only - useful as a screen sharing tool by hosting read only screen session
  • permissive - useful as a real time code collaboration tool

Here is how to setup screen for both scenarios. Note: A downside of a tool like Screen is that everyone needs to learn an editor that runs in terminal. Luckily we all like vim.

First we need to install SSH server because all communication will happen over secure channel:

For the read only scenario, we need to setup guest user account on the host machine. For security reasons we will create a read-only account with rbash (restricted bash) shell which will be used by the programmer we want to pair with to ssh into the host machine we control and join the screen session.

Next we need to setup the guest shell .profile. Add the following to /home/guest/.profile

Here as you can notice "screen -x dalibor/pairprog" automatically will join the session named "pairprog" that is started by "dalibor" user on "guest" user login.

Next we need to install screen on the host machine (if it's not already installed).

For security reasons, screen by default is installed so that other users within the system can not attach to screen session (error you will get is: "Must run suid root for multiuser support."). To allow multi user setup you need to execute following (you might need to change the path if screen is installed in /usr/bin/screen for example):

Then you need to add the following screen config in ~/.screenrc file

Most important lines are "multiuser on" which allows multiuser access in the screen session and "aclchg" command which removes all write and execute permissions for all windows (#) and all commands (?) for user guest. With this setup, host can do anything and guest can just watch the screen or message by using Ctrl-a: wall "hi there".

Finally, communication goes like this: screen session is started by host with:

Guest SSH to the host machine and automatically joins the screen session:

Then they can interact in the same terminal. More on the screen commands here.

If you trust the user you can add full permission with "acladd" command, and usually it's to be done on a shared server. Say we have user1 and user2 logged in on shared server via SSH, user1 has added user2 in the ~/.screenrc file.

And is starting pairprog screen session with:

Then user2 can join that session with:

More info on screen command here in this screen reference. Basic commands are:

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1595979/dalibor.nasevic.jpg http://posterous.com/users/hdKy9bKyhIb5U Dalibor Nasevic dalibor Dalibor Nasevic
Tue, 04 Oct 2011 05:45:00 -0700 Koding in Khayelitsha - great photo http://blog.siyelo.com/koding-in-khayelitsha-great-photo http://blog.siyelo.com/koding-in-khayelitsha-great-photo A great photo from the programming class @glennrob is involved with.

(they're learning ruby)

Koding_in_khayelitsha

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Fri, 23 Sep 2011 03:11:28 -0700 Siyelo Office Graffiti: stop-motion video http://blog.siyelo.com/siyelo-office-graffiti-stop-motion-video http://blog.siyelo.com/siyelo-office-graffiti-stop-motion-video

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Thu, 08 Sep 2011 11:46:00 -0700 Installing a gem in all your global RVM gemsets http://blog.siyelo.com/installing-a-gem-in-all-your-global-rvm-gemse http://blog.siyelo.com/installing-a-gem-in-all-your-global-rvm-gemse
Across different projects like us, you probably have a lot of development gems you like to use. 
E.g. we like;
but obviously it's a PITA (Pain In The ****) to add this gem spec to all your projects.

So, give this a shot;

for x in $(rvm list strings); do rvm use $x@global && gem install <RAD DEVELOPMENT GEM NAME>; done
This installs a specific gem into all your global RVM gemsets. For great justice!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Sun, 31 Jul 2011 15:48:00 -0700 How to bulk delete remote git tags http://blog.siyelo.com/how-to-bulk-delete-remote-git-tags http://blog.siyelo.com/how-to-bulk-delete-remote-git-tags
Our project had a lot of old, unwanted pre-release branch tags in our remote git repo. E.g.;
I needed a one-liner to find all these prerelease tags (i.e. all tags that end in a letter), that deletes them on the remote repo. Then I could do the same on my local.

Given that "git ls-remote" gives output like "<SHA>    refs/tags/<tag>". E.g.;

With a bit of awk and regexp love, we can match that output with;
And we know that to delete a git tag on a remote you use;

So putting it all together we get;

(EDIT: thanks to @jamesconroyfinn for spotting the missing xargs)

Booyaka.

NOTE: execute that above command with extreme predjudice, er I mean, caution. i.e.;

a) make sure you have the tags backed up in your local repo first and 
b) check the output of the awk command first... (everything before "| xargs ..." )

Once you've done a dry-run or two, run that command and watch as those pesky remote tags get deleted.

Similarly for removing these pre-release tags from a local git repo;

(This command is a lot easier to figure out since the output from "git tag -l" is simpler. Alternatively, for synchronization, if you don't have any specific local tags, and are confident that remote has the tags you care about, it may be easier to wipe out all tags and pull them all from origin again.)

Final step: Profit

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Wed, 27 Jul 2011 06:08:00 -0700 Can't drop your Heroku database? http://blog.siyelo.com/cant-drop-your-heroku-database http://blog.siyelo.com/cant-drop-your-heroku-database

If you're trying to drop your database on Heroku, and it's not working, be sure you put it in maintenance mode first. i.e.

Step 1

Step 2

Step 3

???

Step 4

Profit

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Sat, 18 Jun 2011 07:32:53 -0700 Siyelo: An equal opportunity employer. http://blog.siyelo.com/siyelo-an-equal-opportunity-employer http://blog.siyelo.com/siyelo-an-equal-opportunity-employer We don't even mind if our employees wear makeup sometimes...

Imag0142

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Fri, 04 Mar 2011 04:20:27 -0800 Experienced Web Developer wanted http://blog.siyelo.com/experienced-web-developer-wanted http://blog.siyelo.com/experienced-web-developer-wanted

Siyelo is an international Ruby on Rails agency, with solid backing and a growing portfolio of great projects, and happy clients.

Opportunity

This is an opportunity to be a part of an entrepreneurial and focused Ruby/Rails consultancy. We are looking for people with strong web development backgrounds, with a passion for clean code and great software.

We're all "full-stack" developers, so whilst you don't necessarily need to know how to rewrite PacMan in Javascript, familiarity with jQuery and HTML/CSS is needed. We care about quality too. Writing tests first using modern frameworks should be second nature to you.

We are working on an exciting mix of improving and scaling existing apps and developing entirely new apps. Our team is fast, talented and independent, and we encourage Open Source contributions and community participation.

Requirements

  • 3+ years web development or related experience
  • Experience in Object Oriented languages & domain modeling
  • Agile development practices: TDD/BDD, pair programming, refactoring
  • Relational databases: PostgreSQL or MySQL
  • English proficiency a must.


Highly Regarded

  • Ruby / Python / Smalltalk / Java experience
  • UI/UX design (HTML, CSS, Javascript)
  • jQuery or similar framework
  • NoSQL databases
  • Open source contributions
  • Git & Github


How to Apply

Please send your CV (including any portfolio/open source links) to jobs@siyelo.com.

[Optional] For BONUS points, you can apply using our fun little Github application.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1595979/dalibor.nasevic.jpg http://posterous.com/users/hdKy9bKyhIb5U Dalibor Nasevic dalibor Dalibor Nasevic
Sat, 05 Feb 2011 02:14:27 -0800 RubyFuZa conference, Cape Town - pics http://blog.siyelo.com/rubyfuza-conference-cape-town-pics http://blog.siyelo.com/rubyfuza-conference-cape-town-pics

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Thu, 16 Dec 2010 10:53:25 -0800 The Siyelo fridge http://blog.siyelo.com/the-siyelo-fridge http://blog.siyelo.com/the-siyelo-fridge After a visit from our favourite Argentinian friend, this is what our fridge looks like;

Photo

So much Quilmes, so little time!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Wed, 01 Dec 2010 01:23:45 -0800 A Zerigo DNS template for Heroku and Google Apps http://blog.siyelo.com/a-zerigo-dns-template-for-heroku-and-google-a http://blog.siyelo.com/a-zerigo-dns-template-for-heroku-and-google-a
While recently switching over a client's web app, and their mailservers to Google Apps, I found that Zerigo's template feature would make me less likely to murder kittens whenever I'm asked to do anything related to DNS.

Pastedgraphic-10

So here's our Zerigo DNS template for a Heroku + Google Apps setup.

Part A - Heroku

Pastedgraphic-7


Part B - Google Apps Mail

Pastedgraphic-6

Part C - Google Apps miscellany 

This is for webmail/docs/calendar

Pastedgraphic-8

And there you go! Never kill a kitten (again).

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Thu, 07 Oct 2010 00:09:17 -0700 RailsConf 2010 - some pics courtesy Dr Nic http://blog.siyelo.com/railsconf-2010-some-pics-courtesy-dr-nic http://blog.siyelo.com/railsconf-2010-some-pics-courtesy-dr-nic Check out the iphone pic of everyone on their iphones at the dinner table. Very meta.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Thu, 23 Sep 2010 03:39:00 -0700 Git workflow for a staging environment with Heroku and GitHub http://blog.siyelo.com/git-workflow-for-a-staging-environment-with-h http://blog.siyelo.com/git-workflow-for-a-staging-environment-with-h
Are you using
  - git ?
  - GitHub ?
  - Heroku ? ( or some other nice git-backed hosting? ) 
  - multiple Heroku environments  ? (e.g. Production/Staging) 
  - good git team workflow practices ?

Then check out this great post by the folks at New Forge;

   Git workflow for a staging environment with Heroku and GitHub

which tells you how to manage your git branches and keep them in sync with your Heroku instances. 

And here are some handy shell aliases to go with your newfound uber git/GitHub/Heroku workflow;

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts
Wed, 25 Aug 2010 08:05:00 -0700 CanCan - make up your mind! http://blog.siyelo.com/cancan-make-up-your-mind http://blog.siyelo.com/cancan-make-up-your-mind
If you're using CanCan and came across an error like this;

1
The :class option has been renamed to :resource for specifying the class in CanCan.

And you duly updated your controller code from;

1
authorize_resource :class => FundingFlow

To something like this;

1
authorize_resource :resource => FundingFlow

Since, like all good programmers, you do what you're told by error-messages. But then like some sick joke it starts mocking you with the inverse error message i.e;

1
The :resource option has been renamed back to :class, use false if no class.

Before you go and stalk Ryan B (the CanCan author) with a fully automatic assault rifle, first check your CanCan versions.

1
2
3
4
$ gem open cancan
Open which gem?
 1. cancan 1.1.1
 2. cancan 1.3.2

Ah ha. And if you're using RVM like we do, then your default.gems might be specifying a different version (which in our case manifested in our staging server, not on local development).

So by making sure you're using the latest version (>= 1.3.2), and using the :class syntax i.e.

1
authorize_resource :class => FundingFlow

, you might save yourself a murder (or at the very least a weapons) charge.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/219833/glenn.png http://posterous.com/users/36ENp3Gatg8V Glenn Roberts glennrob Glenn Roberts