Some of you may be aware of my grandiose plans with my twitter mini-framework named twuckoo. For my part I am constantly thinking about -hopefully reasonable- ways that it could be used for the better of mankind :)

The other part of the story is my enthusiasm with Pragmatic Programmers books. I have recently started Pragmatic Thinking and Learning by Andy Hunt which is also a very good one and found the familiar “resuming card” at the end. This card sums up the wisdom of the book in short phrases just so that you can recall what you read quickly. It is a great idea and can be found in other PP books, too.

So I asked at a PP email address which seemed to be closest to copyright questions whether I have the right to do this. To my surprise, it was the author himself, Andy Hunt, who answered me and kindly gave me permission for the book in question. (Once again, thank you, Andy!)

So there you have it, a twitter account that will serve you an advice each day just so that you can “refactor your wetware” (the subtitle of the book) and hopefully help you be a better craftsman.

And now, my little twuckoo, on to world domination!

To be able to experiment freely and find a store for my twuckoos and other goodies I have recently purchased a Linode 360 slice and had Ubuntu 9.04 installed on it. Next thing was setting up ruby (ruby 1.8.6, to be precise).

When deciding about how to install ruby, in part I wanted to have flexibility but mostly I wanted to feel like I am a professional sysadmin for some hours so I balked at pre-built ruby packages and went with the roll-your-own approach. I’ll summarize below the process and some pitfalls I encountered so it might help someone.

Some basic tools

First, you will need wget (or curl) to download the sources you will need along the way, so:

$ sudo apt-get install wget

Also, before you stare dumbly at the screen (like I did) wondering why can’t the stupid machine run make when the Makefile is clearly there in the directory , don’t forget to install make:

$ sudo apt-get install make

Updating the package repos

Plus, since we’ll be installing packages that are found in the “universe” namespace (or whatever it is called) you should uncomment the below two lines in /etc/apt/sources.list :

deb http://us.archive.ubuntu.com/ubuntu/ jaunty universe
deb-src http://us.archive.ubuntu.com/ubuntu/ jaunty universe

… and then update your package index:

$ sudo apt-get update

Installing some packages ruby needs

Before we download and build ruby, however, it is recommendable to have the zlib and openssl libraries so ruby can already bind to them. This is one of the things that is a lot easier to see with hindsight, but here I am, blogging this to you:

$ sudo apt-get install zlib1g zlib1g-dev zlibc
$ sudo apt-get install openssl

It turns out from this thread, that the zlib bindings are part of ruby since 1.8.6 so you will not need the libzlib-ruby package.

Now, on to ruby itself.

Ruby & Rubygems

$ wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.6-p369.tar.bz2
(untar and cd to new directory)
$ ./configure
configure: error: no acceptable C compiler found in $PATH

Piece of cake:

$ sudo apt-get install gcc
$ ./configure
configure: error: in `/home/balint/ruby-1.8.6-p369':
configure: error: C compiler cannot create executables
See `config.log' for more details.

A bit harder, but I have quickly found the answer here, and then did:

$ sudo apt-get install libc6-dev g++
$ ./configure
$ make
$ sudo make install
$ ruby -e "p 'hello from linode slice'"
"hello from linode slice"

Rolling!

However, we all know that a ruby installation without gems is a toothless tiger (lion?) so we’ll install rubygems last, first downloading the source, and then installing it:

$ wget http://rubyforge.org/frs/download.php/57643/rubygems-1.3.4.tgz
(untar and cd to new directory)
$ sudo ruby setup.rb

If you want to use gems stored on github (and you probably do) it is convenient to add the gem github repository to your gem sources:

$ gem source -a http://gems.github.com
$ sudo gem install balinterdi-twuckoo

Ok, that’s all. I hope you have found this useful.


Note:

If you receive an error message similar to the following when trying to install a gem:

/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- zlib (LoadError)

Then you need to install the appropriate lib package and recompile ruby. Go to the directory where you unpacked the ruby source to and do:

$ make clean
$ make
$ sudo make install

twuckoo

by balint

I am reading Andy Hunt’s excellent Pragmatic Thinking and Learning book. There is a section about so called “oblique strategies”, short, mysterious phrases that exercise your mind and make you look at problems from another perspective (e.g “repetition is a form of change”).

The suggested intake was once a day and there was a free application that did just this for Apple computers. However, the application was so outdated that I could no longer run it on my laptop. So, I set out to write that application and after a bit of thinking decided to make a twitter account where I (”I” meaning a script that I wrote :) ) would post an oblique strategy each day and then just follow that account. This way, I can also spread the knowledge around.

Thus Twuckoo was born. Twuckoo is a simple program (relying on twibot for communication with twitter) that lets you periodically post a message on a twitter account. It can fetch the messages from a file, from a database, from the web or whereever you want it to retrieve them from. Its very modular in nature so it delegates the task of getting the next message to twitter and storing the posts to the module. here is currently one generic module, the one that fetches them from a file, and one that fetches them from wikipedia’s main page. I strongly hope that it is very easy for you to write your own module for your own purpose. Twuckoo aims to follow the “provide-what’s-needed-and-then-just-get-out-of-the-way” principle. Go check out the README for further details.

It’s quite easy to install and run. You can find an example for the file-fetcher module at http://twitter.com/daily_oblique and http://twitter.com/wikipedia_tfa grabs “Today’s Featured Article” from wikipedia and posts the title and the link so you can grow a little wiser each day :)

Since it is modular it’s very extensible. I kept the API very simple so writing modules should be a piece of cake. Each module has to define the following methods:

  1. load_tweets Loads the messages that can be twittered.
  2. next Gets the next message that will be posted.
  3. store(tweet) Store the tweet after it had been posted.

Once more, I encourage you to scan through the README, devise your own module and let me know about it. Any feedback is very welcome!

Note: For my Hungarian-speaking readers, I gave a lightning talk about twuckoo at the latest budapest.rb meetup.

We all love playing games, from poker to soccer, from hide’n seek to … trivia! I am a great fan of this latter and also of Rails apps so it was kind of natural for me to come up with the idea of using all the data in your Rails app to serve as the basis of trivia questions.

The ingredients are few and basic. You have a class with an attribute that is comparable and makes sense to compare (the population of states is a good example, the zip code of addresses is a counter-example).

Installation

Install the gem

  1. Install the gem through Rails’s config.gem
  2. Put this:

        config.gem "balinterdi-acts_as_trivia", :source => "http://gems.github.com",
    :lib => "acts_as_trivia"
    

    in your environment.rb and then run rake gems:install or rake gems:unpack.

  3. Install it system-wide with the gem command
  4.   gem install acts_as_trivia --source http://gems.github.com
    

Make your app act as a trivia

You just have to run the provided trivia from the root of your Rails application:

  ./script/generate acts_as_trivia

Create trivia questions easily from the command line

    ./script.generate acts_as_trivia_record country population name

This trivia question will be about the population of countries and the name of each will be used by the provided helpers for the sake of displaying something unique of each country.

Create the pages to answer and assess trivia

The acts_as_trivia gem only aims to provide a clean interface and the logic, so you will have to create the new controller action of the TriviaAnswersController and the corresponding view:

  /users/:user_id/trivias/:trivia_id/trivia_answers/new

However, you can take a look at these files in the rails app generator or just directly copy them.

Get right in the game

Instead of going through the above steps, you can use a rails app generator to set up a trivia app quickly:

rails my_shiny_app -m
http://gist.github.com/raw/107361/f31caad451f0cca699288700aa3d98291a259fd1/gistfile1.rb

Once you go through the setup steps of the app generator, you have everything you need to have a functioning trivia app, so you can go to:

  /users/1/trivias/1/trivia_answers/new

And if you created model instances you can already answer your first trivia question. For a more technical (and more complete) description, please see the README. Also, since this is a beta version, please make sure to report any bugs you might come across.

The actions of a web application basically fall into three categories based on their access rights:

  1. Actions with anonymous access
  2. Actions the user has to be logged in to access. (authenticated actions)
  3. Actions the user needs a certain privilege for to access (authorized actions)

At the implementation level, the first category is obvious, since the actions in this category do not have to be protected. So let’s shift our attention to the second and third category and consider how access protection for these can be achieved in Rails applications.

Both of these are best done with before filters since they run before the control is passed to the action’s code and provide a DRY way to protect several actions.

Authenticated actions

Access restriction is quite straightforward once you have a basic library that provides a method to see if a user is logged in (see restful-authentication for a full-scale solution):


class ProfilesController < ApplicationController
  before_filter :login_required
  (...)
  def login_required
    redirect_to login_path unless logged_in?
  end
end


Authorized actions

This can be more tricky since there is a great deal of possibilities of what privilege is needed to access a certain action (e.g only admins can see the full user list, only managers can edit the employees’ records, etc.).

I realized there is one very prevalent type, though, the owner-type access. Only the owner of a blog can modify its data, only the user of a profile can edit its attributes, only the leader of a project can set its deadline, etc. The number of these is endless and I bet there are basically no sites where this does not come up.

Also, the pattern of this access restriction is pretty much the same in all cases. There is the resource to be protected, its owner and the user currently logged in. For access to be granted, the owner of the resource needs to match the current user. So why not extract the pattern to be reused?

Only owner

Hence the only-owner plugin (I know I suck at naming projects) was born. By default, it will create a before filter in the controller which checks if it is the owner that wants to access the resource. If it is, access is granted. Otherwise, the user is redirected to the login path. Convention over configuration makes a lot of sense so to get up and running you only need to do these two things:

Install the plugin:

./script/plugin install git://github.com/balinterdi/only_owner.git


“Tag” the controller to be protected:

  class ProfilesController > ApplicationController
    only_owner
    (...)
  end


That assumes that the profile can reach its user through the user association and that there is a find_profile method in scope in the controller. If your association or the finder method is named otherwise, you can pass the appropriate parameters to define them (:owner and :finder, respectively). As a -sensible, I reckon- convention, all methods in the controller except the new, create, index and show ones will be protected by default. Once again, this can be overridden with the usual :only and :except parameters.

I encourage you to scan through the README for the options and especially, as always, to give me some feedback.

Next Page »