On the Subject of Average Body Weight by Day of the Week

I have been diligently keeping track of my weight, every day, for the past 10 years. It’s taken significant effort but persistence’s my middle name.

Here’s a chart of my average weight by day of the week:

on the subject of body weight

Sortable Lists With JQuery in Rails

Drag ‘n Drop sortable lists are a great way to provide a UI for sorting, well, lists of things. Most Rails examples out in the wild use prototype/scriptaculous and the built in Rails javascript helpers. In this walkthrough we’ll provide the same functionality using JQuery instead. We will not be using the built in Rails javascript helper. Instead we’ll write Unobstrusive Javascript using JQuery.

For this example we’ll use a UserStory and a Task model:

or tags like

? Same thing is happening with Javascript: separate behavior from content and presentation. So instead of saying foo, you want to create a plain old link, and unobstrusively change the click’s behavior via javascript. The basic feel for this looks like:

1
2
<!-- in your view -->
<a id="foo" href="http://foo.info">This is foo!</a>
1
2
3
4
5
6
7
//in application.js (possibly)
$(document).ready(function(){
$('#foo').click(function(){
//handle the click
return false; //cancel the browser's traditional event.
});
});

Just like we use CSS selectors to style an element, we can use JQuery selectors to describe the behavior of the element. Just like you may have styles.css, you may have application.js. This separation of behavior helps avoid cross browser inconsistencies, dry up and reuse your code, as well as provide graceful degradation to user agents that don’t even support Javascript. For instance, a form may be submitted via AJAX if the browser supports Javascript, or the traditional action may execute if it doesn’t. I’ve come to the point where looking at something like foo has the same effect as seeing style code in the middle of an HTML document: repugnance.

Set yourself up for JQuery

Head over to the JQuery site and download the minified (production) version of JQuery. The sortable() function is part of JQuery UI, which you can download from here. Place both under public/javascripts and include it on your layouts. Pretty standard stuff.

Add a content block on your layout for :javascript. This pattern was picked up while hacking on the bostonrb site’s code and I’ve stolen it for my own projects. It is a great way to throw UJS in your views. This should be at the bottom of your layout, right before the closing tag (or in it’s own partial along with other javascript related stuffs):

1
2
3
4
5
6
7
<html>
<head><title>My boring blog</title></head>
<body>
...
yield :javascript
</body>
</html>

Having that out of the way, we need to set up jQuery’s AJAX requests. We can use JQuery’s $.ajaxSetup() hook to set the appropriate headers. Additionally, we’ll include Rails’ authenticity token on our AJAX Post requests.

For this to work, we need to store the Rails authenticity token somewhere. One option is to simply store it on a javascript variable as described here. Add this to your layout:

1
<%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %>

Then, throw the following on your public/javascripts/application.js file - I haven’t seen any downside to this, but leave a comment if you do.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//public/javascripts/application.js
// This sets up the proper header for rails to understand the request type,
// and therefore properly respond to js requests (via respond_to block, for example)
$.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})
$(document).ready(function() {
// UJS authenticity token fix: add the authenticy_token parameter
// expected by any Rails POST request.
$(document).ajaxSend(function(event, request, settings) {
// do nothing if this is a GET request. Rails doesn't need
// the authenticity token, and IE converts the request method
// to POST, just because - with love from redmond.
if (settings.type == 'GET') return;
if (typeof(AUTH_TOKEN) == "undefined") return;
settings.data = settings.data || "";
settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
});
});

Having done that, let’s prep our models. Let’s assume you’ve created the UserStory and Task classes with the required has_many and belongs_to associations.

Models set up.

The models require just a few things: the acts_as_list plugin and a position attribute on the tasks table

1
2
3
4
5
6
7
8
9
$ script/plugin install git://github.com/rails/acts_as_list.git
Initialized empty Git repository in /Users/hgimenez/code/foo/vendor/plugins/acts_as_list/.git/
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 13 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (13/13), done.
From git://github.com/rails/acts_as_list
* branch HEAD -> FETCH_HEAD
$
  • Create a position column on the tasks table with:
1
2
script/generate migration add_position_to_tasks
rake db:migrate
  • Add acts_as_list :scope => :user_story to the Task model.
  • Optionally, add default_scope => 'position' to the Task model.

View setup

The idea is to create an

    of tasks that belong to a given user story. Each
  • contains a task and we have to “stage” the element’s IDs so that when we serialize the list using JQuery, the task’s IDs are sent over to the server via an AJAX request.

    We also create a span with a class of “handle”, which is where the user can hold on to when dragging and dropping tasks around.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    <ul id="tasks-list">
    <% @user_story.tasks.each do |t| %>
    <li id="task_<%= t.id -%>">
    <span class="name">
    <%= t.name -%>
    </span>
    <span class="handle">[handle]<span>
    </li>
    <% end %>
    <ul>

    (Unobstrusive) javascript setup

    Now we are ready to wire in the javascript on your view. At the bottom of your view, and using the :javascript content block created earlier, use JQuery’s sortable() function and attach it to the #tasks-list element:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    <% content_for :javascript do %>
    <% javascript_tag do %>
    $('#tasks-list').sortable(
    {
    axis: 'y',
    dropOnEmpty:false,
    handle: '.handle',
    cursor: 'crosshair',
    items: 'li',
    opacity: 0.4,
    scroll: true,
    update: function(){
    $.ajax({
    type: 'post',
    data: $('#tasks-list').sortable('serialize') + '&id=<%=@user_story.id-%>',
    dataType: 'script',
    complete: function(request){
    $('#tasks-list').effect('highlight');
    },
    url: '/user_stories/prioritize_tasks'})
    }
    })
    <% end %>
    <% end %>

    This is basically saying: Take the element with an ID of #tasks-list and make it sortable. Do an HTTP POST to the user_stories/prioritize_tasks path with the serialized tasks-lists as data. Note that we’re also appending the user_story id as a post parameter so that our controller action knows which tasks to prioritize.

    Feel free to go over the sortable() documentation to tweak the options.

    Controller set up

    The controller’s work is to take the parameters sent in from the view and to set the position attribute of each of the user story’s tasks. The parameters received in the controller look something like:

    1
    2
    
    params.inspect
    => {"authenticity_token"=>"9HJQs99d4vqhLwjPAdC8uSLwjPAd4OpbaJQs99dFCch8XisI=", "id"=>"1", "task"=>["2", "1"]}

    As expected, we receive the Rails authenticity token, as well as the id (the UserStory ID) and an array of task IDs (params['task'] contains task IDs in the order specified by the user).

    Here’s the implementation of the prioritize_tasks action:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    def prioritize_tasks
    user_story = UserStory.find(params[:id])
    tasks = user_story.tasks
    tasks.each do |task|
    task.position = params['task'].index(task.id.to_s) + 1
    task.save
    end
    render :nothing => true
    end

    Route setup

    Almost there. The one thing that’s missing would be adding a collection route to the user_story resource for the prioritize_tasks action:

    1
    2
    
    # add the :collection option
    map.resources :user_story, :collection => { :prioritize_tasks => :post }

    This pretty much wraps it up! This process will become easier as Rails core evolves and the Javascript framework becomes easier to swap out. It is known that Rails 3’s helpers will not produce inline javascript. Instead, they will add hooks to your DOM elements in the form of HTML5’s custom data attributes which then can be used by unobstrusive javascript code to add the appropriate behavior to the DOM elements. Even though Rails will continue to ship with the Prototype/Scriptaculous frameworks by default, JQuery will be easier to plug in, and the Rails helpers that simply add data attributes to your DOM elements can be used to achieve all sorts of presentation behavior.

    Regardless of that, the closer you are to your Javascript, the better you’ll understand how the pieces play together and the more control you’ll have over the app’s client side behavior.

    Resources

PostgreSQL, Rails, and Why You Should Care

MySQL is the most popular RDBMS used to back Ruby on Rails applications. However, there are many reasons to try out PostgreSQL. It offers performance, efficiency, feature set, configurability, and seamless integration in your Rails projects.

PostgreSQL Features

PostgreSQL supports all of the features you would expect from an open source RDMS, including many that are found in commercial databases (Oracle, DB2, SQL Server) such as:

  • The basics: views, triggers, indexes, foreign keys, ACIDity, transactions, query optimization, comprehensive SQL support and data types, autovacuum (keeps your table statistics up to date).
  • The not so basics: Features that may not be seen on other DBMSes include reverse, partial and expression indexes, table partitioning, table inheritance, cursors, data domains, user-defined operators, arrays and regular expressions.
  • Procedural Languages: analogous to Oracle’s PL/SQL or SQL Server’s T/SQL, PostgreSQL supports internal procedural languages for when you need to get down and dirty with the data. Additionally, it supports a wide range of languages including Ruby.
  • Rules, which pretty much allow you to rewrite an incoming query. A typical use of Rules is to implement updatable views.
  • Multi-Version Concurrency Control: MVCC is how PostgreSQL (and other DBMSes) deal with concurrency and table locking. In practical terms, it allows for database reads while the data is being writen.
  • Write-Ahead-Log: the WAL is the mechanism by which PostgreSQL writes transactions to the log before they are written to the database. This increases reliability in the unlikely event of a database crash, as there will be a transaction log by which to rebuild the database’s state. PostgreSQL includes many configuration parameters to tweak the behavior of the WAL.
  • PostgreSQL scales up by efficiently using multi-core servers. It also sport an asynchronous processing API. Subselects are fast, you can refer to tmp tables more than once in a query and it can use more than one index per query, making it suitable for data warehousing applications as well.
  • tsearch2, which is PostgreSQL’s highly efficient full text search component. If you are committed to PostgreSQL, this is a very high performant search engine for PostgreSQL (as an alternative to solr or sphinx, for instance), with the added benefit that you’re not running a separate daemon or search service.
  • PostGIS for geospacial objects.
  • There are many replication options, although non of them are built into the core. This will change very soon, though.
  • You can tweak its brains out: open up postgresql.conf, and you’ll find many configuration options that can be tweaked to your application load and server capabilities. If you’re like me, this is lots of fun. I will say, however, that it will take time to understand many of the options and how they affect each other.
  • Excellent documentation, which not only goes through the basics of setting up and using PostgreSQL, but really gets into the details of the inner workings of the system. This is an invaluable resource, not only for day-to-day development but also for tweaking the database’s configuration files.
  • Much more in the contrib packages.

PostgreSQL License

PostgreSQL is released under a BSD License, and as such it is truly an Open Source Project. There are many contributors to the project, both individuals who donate their time as well as companies that improve the codebase (such as EnterpriseDB and Command Prompt). If you are looking for the PostgreSQL gatekeeper, you’ll be chasing your tail: There’s no such thing. It is truly “Free Software”.

So, what is it? MySQL or PostgreSQL?

Historically, MySQL was built with performance in mind, whereas PostgreSQL was built with features in mind. The ease of use of MySQL earned it the popularity seen on most open source web application developers. Since then, however, two things have happened: PostgreSQL has become much faster and efficient, and MySQL has become more feature-rich. In my mind, the performance or feature argument is no longer valid for web applications. Both databases have their strengths and weaknesses and as you work out an expertise on either one of them it will become a moot point. Some of the lacking MySQL features are of interest only to DBAs, not web app developers, although this may be a consideration for larger shops and deployments.

One of the major reasons for trying out PostgreSQL, regardless of it’s feature set, is it’s license and community. This can’t be more true these days, when MySQL AB was consumed by Sun Microsystems, which in turn recently got acquired by Oracle. While I doubt that the product itself may die off, the fact that the copyright to the code, and the direction of the database system itself may and will be dictated by a company like Oracle is a deal breaker for me. At this point it is hard to tell if this is good or bad for MySQL and the community around it, but it definitely shows turmoil in the MySQL ecosystem. Note that I am not implying that Oracle sees MySQL as a threat to Oracle DB. In fact, I believe that MySQL satisfies a completely different niche.

On the other hand, PostgreSQL is a community effort along the same lines as the Ruby and Rails communities. This makes it a more attractive option as the direction of the project is community driven, immune to corporate politics and revenue motives.

Attach Non Image Files in Rails With Paperclip

Paperclip has pretty much become the standard when it comes to attaching files to models in Rails. It has a very easy to use API, allows the user to create her own post-processing code (such as OCR or others), and provides callbacks for before and after post-processing.This post does not cover getting started with paperclip. There are plenty of other posts that cover that. The intent is to get you up and running on using paperclip to attach non-image files.

Out of the box, the default post processor invoked upon upload is the Paperclip::Thumbnail processor. This processor creates thumbnails of an image based on the styles hash passed to the has_attached_file method. If you want to upload word documents, excel files, and other non-image data, the Thumbnail processor will fail, and the attachment will not succeed. This processor does not check if the file itself is an image, and tries to call ImageMagick’s identify command on the file anyways.

Paperclip makes solving this extremely simple: prevent the post processing from happening when the file is not an image. Just like on ActiveRecord callbacks, you can return false on paperclip’s before_post_process callback to avoid the processing from happening in the first place.

One possible solution is to put the following in whatever model you’re using paperclip on:

1
2
3
4
before_post_process :image?
def image?
!(data_content_type =~ /^image.*/).nil?
end

In this case, we’ve created an image? method which returns true if the content type starts with the string image (as in ‘image/png’, ‘image/jpeg’, etc). What’s neat about this is that this same method can be used in your views to either render an image_tag, or something else such as an icon or the file’s name, depending on whether the file is an image.

Really Silly Percentage Calculation in Ruby

Here’s a silly way to calculate percentages of numbers in a Ruby project or Rails app.

The end result of this is having created a few methods for Ruby numeric classes that allow you to calculate percentages:

1
2
3
4
5
6
>> 23.456.five_percent
=> 1.1728
>> 100.46.seven_percent
=> 7.0322
>> 95.fifty_percent
=> 47.5

To accomplish this, we’ll use use meta programming to add the methods to the Fixnum and Float classes.

First, create a way to translate numbers in English to numeric values. This was taken from a thread at ruby-forum.

Then, we’ll make use of Ruby’s method_missing to find out if this is a *_percent method and act accordingly. The percent_method? method returns true if it is, false if it ain’t.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
module NumberPercentageExtension
module InstanceMethods
ENGLISH_VALUE = {}
%w| zero one two three four five six seven eight nine ten eleven
twelve thirteen fourteen fifteen sixteen seventeen eighteen
nineteen |.each_with_index{ |word,i| ENGLISH_VALUE[word] = i }
%w| zero ten twenty thirty forty fifty sixty seventy eighty
ninety|.each_with_index{ |word,i| ENGLISH_VALUE[word] = i*10 }
ENGLISH_VALUE['hundred'] = 100
def percent_method?(method)
tokens = method.to_s.split('_')
return false if tokens.size < 2
is_percent = tokens[-1] == 'percent'
tokens[0..-2].collect { |word| is_percent &&= ENGLISH_VALUE.has_key?(word) }
return is_percent
end
def method_missing(method, *args)
if percent_method?(method)
method.to_s.split('_')[0..-2].map { |word| ENGLISH_VALUE[word] }.sum * self / 100.to_f
else
super
end
end
end
end

We also want respond_to? to be aware of the new *_percent methods, so we include that as well.

1
2
3
4
5
def respond_to?(method)
return true if percent_method?(method)
super(method)
end

Finally, include the module in Numeric:

1
2
3
4
Numeric.class_eval do
include InstanceMethods
end

The full code listing can be found in this gist.

Flash Messages Rails Helper Plugin

I just pushed my first Rails plugin to github(http://github.com) .

This is dead simple: it provides a helper for showing flash messages on your Rails apps with scriptaculous appear/fade effects.

The readme

To install it:

1
ruby script/plugin install git://github.com/hgimenez/sexy_flash.git

Installing FANN and Ruby-fann on Fedora Core 9

As of this writing, the ruby-fann library requires FANN 2.1. Since that version of FANN is still in beta, it is not available from the yum repositories yet (as far as I know). Compiling the source is trivial, however:

  • Download the source code for FANN 2.1beta from any of the mirrors found here: http://leenissen.dk/fann

  • After extracting it, run the usual: ./configure make sudo make install

  • Make sure the files are present: ls /usr/local/lib |grep fann libdoublefann.a libdoublefann.la libdoublefann.so libdoublefann.so.2 libdoublefann.so.2.0.1 libfann.a libfann.la libfann.so libfann.so.2 libfann.so.2.0.1 libfixedfann.a libfixedfann.la libfixedfann.so libfixedfann.so.2 libfixedfann.so.2.0.1 libfloatfann.a libfloatfann.la libfloatfann.so libfloatfann.so.2 libfloatfann.so.2.0.1

Since these libraries where just installed, you have to run ldconfig in order to cache them and create the required links. This was the gotcha: ldconfig /usr/local/lib

Now, use ruby-gems to install the ruby-fann bindings:

sudo gem install ruby-fann

Cannot Connect to SQL Server 2005 Express

(Very old news, but I keep having to go back to this)

If your SQL client (ie: SQL Server Mangement Studio, Toad, Embarcadero, etc) can’t connect to a MS SQL Server 2005 Express Edition installation, follow these steps:

  • Launch SQL Server Configuration Manager

  • Click on SQL Server 2005 Network Configuration

  • Click on Protocols for MSSERVER => right click on TCP/IP => properties

  • Click on Protocols, make sure it is enabled

  • Click on IP Addresses and make sure under each of the IP1, IP2 and IPAll, that the port is 1433

  • Click on SQL Native Client Configuration

  • Click on Client protocols => TCP/IP => right click => Properties => make sure the port is 1433

  • Right click on Alias => New alias => Alias: any name. Port:1433.Server`: host name for the SQL Server Express instance

  • Try to connect

GnuPG on MacOS X (Apple Mail)

  • Install GnuPG. http://macgpg.sourceforge.net/

  • Create a key pair: Open terminal and type: gpg --gen-key Follow on screen instructions. ** Choose a key length of 4096, and an expiration of 0 (never expires). Be patient, generating the keys took about an hour.

  • Install GPGPreferences. http://macgpg.sourceforge.net/

  • Go to System Preferences, and open GnuPG (located at the bottom under “Other”). Go to the keyserver tab, and check: "Automatically retrieve keys from server while verifying"./r "Include subkeys".

  • Install GPG Keychain access. http://macgpg.sourceforge.net/. Open it up after the key has been generated (step 2). Import other’s keys for people you will exchanged signed messages with.

  • Install GnuPGMail plugin. http://www.sente.ch/software/GPGMail/English.lproj/GPGMail.html Open Mail, and go to preferences (Apple + ,). Defaults are fine.

  • Sign and send an email.

Stop Spam on Sendmail

Lately the number of spam messages has grown very rapidly on my organization’s sendmail server. There’s a few things you can do. Here are two which helped considerably:

  1. Deny access to the domain: You can add the domain name to /etc/mail/access followed by the word REJECT. After editing the access file, you have to run make on the /etc/mail directory.

  2. Use online spam blacklists: There are many of these lists, such as Spamhaus ROKSO, Spamcop, or the Open Relay Database. These are organizations that basically provide a list of spammers. Many thanks to all of you!. To use their lists on sendmail, add the following lines to your /etc/mail/sendmail.mc file before the MAILER lines:

FEATURE(dnsbl',relays.ordb.org’, Rejected - see http://ordb.org/')dnl FEATURE(dnsbl’,bl.spamcop.net',Rejected - see http://spamcop.net/’)dnl FEATURE(dnsbl',sbl.spamhaus.org’,Rejected - see http://www.spamhaus.org/')dnl</code> After editing sendmail.mc, you have to rebuild sendmail.cf. Here's how I did it: <code>$ cp /etc/mail/sendmail.mc . $ m4 ../m4/cf.m4 sendmail.mc > sendmail.cf $ cp /etc/mail/sendmail.cf /etc/mail/sendmail.cf.BAK $ cp sendmail.cf /etc/mail/sendmail.cf $ cp: overwrite/etc/mail/sendmail.cf’? y $ /etc/rc.d/init.d/sendmail restart

Any more ideas to stop spammers? I honestly do not understand why these people keep spamming. Problems man, serious problems! Don’t they realize that there is no way people will read their emails, not to mention buy their products or fall for their scams? Or will they?