A collection of computer systems and programming tips that you may find useful.
 
Brought to you by Craic Computing LLC, a bioinformatics consulting company.

Tuesday, February 26, 2013

General approach to building Rails applications with Devise

I have built a number of complex Rails applications that include user authentication. I want to describe my general approach to getting these up and running.

In most of them I chose the Devise gem to handle authentication and added a number of custom fields to the User model (first name, last name, etc). The gem documentation and this Railscast can help you get started with all that.

One approach is to build your core application without authentication and then add it in at a later stage but I don't like that.

Authentication can quickly get very complicated once you start adding user confirmation via email, an admin role and other custom fields. I prefer to get all that machinery up and running in the context of a very simple application and only then add my real application code into it.

Similarly, when I'm starting with a new application I don't usually hit on the right data architecture right away. That leads to me adding new columns to my database tables and models over time and it always involves quite a lot of 'rake db:rollback / rake db:migrate' operations. I prefer to go through this phase without the extra baggage of authentication, and often, without worrying a lot about CSS etc. I just need to try several alternate views of the problem before I settle on a final design.

So may approach is to build two applications side by side. The first is a minimal application with, say, a single table (usually called 'posts') to which I add Devise and configure all the options that I want.

This is a very useful piece of code for other applications, so I always create a good README and store a copy of the code for future use.

Separately I work through my core application and, once that is working, I condense all the migrations that add/remove/rename columns into a few 'clean', simple migrations.

Finally I add the core application code to the minimal authenticated application. That way it is easier for me to update the controllers, etc. to use authentication.

The bottom line is that you want to minimize the number of moving parts in the early stages of a new application design. This is a simple approach that works very well for me.


Thursday, February 14, 2013

Street Intersections in Google Maps

I need to display Google Maps with markers placed at street intersections, starting with an address that looks like '13 Av E / E John St, Seattle, WA'.

Google Maps doesn't know how to parse this and gives me a location on John Street but it's not correct.

Various sources on the web tell you use 'at' as the conjugation between the two streets - so '13 Av E at E John St, Seattle, WA'

This works fine in most cases but in some, like this one, it fails - this gives the intersection of 13th Ave East and E Prospect (7 blocks away).

What seems to work much better is to use 'and' ... '13 Av E and E John St, Seattle, WA' is spot on.


Friday, February 8, 2013

Jquery snippet to disable / enable links on a page

Here are two approaches to hiding all the anchor (a) tags on a page while retaining the html that was contained within the tags. They both use Jquery.

Approach #1 - Remove all the 'a' tags while retaining their content - no way to retrieve the links, etc.

This lets you effectively disable all the links without losing any text. Using the .html() call instead of simply .text() means that any images or other formatting is preserved.

    $("a").each(function() {
      var t = $(this).html();
      $(this).replaceWith(t);
    });

Approach #2 - Reversibly Hide and Show the tags

Replace the 'a' tags with 'span' tags and store the original tag pair in a custom data attribute

Custom data attributes all have the prefix 'data-' followed by a unique name. You can store arbitrary data in these. With this approach I am storing the original 'a' tag pair and its contents.

In the example, my custom data attribute is called 'data-craic' and note that the 'span' tags are given a unique class (I'm using 'hidden-link') that allows you to identify them

To hide/disable the links:

  $("a").each(function() {
    // Get the html within the 'a' tag pair
    var t = $(this).html();
    // Get the entire tag pair as text by wrapping in an in-memory 'p' tag and fetching its html
    var original_tag = $(this).clone().wrap('<p>').parent().html();
    // Replace the 'a' tag with a 'span' - put the original tag in the data attribute
    $(this).replaceWith("<span class='hidden-link' data-craic='" + original_tag + "'>" + t + "</span>"); 
  });

To show/enable the links:

  $(".hidden-link").each(function() {
    // Retrieve the original tag from the data attribute
    var original_tag = this.dataset.craic;
    // Replace the 'span' with it
    $(this).replaceWith(original_tag);
  });

At least in my use cases I have not had to encode the original 'a' tag pairs but base64 encoding might be a good idea to avoid any possible unintended consequences.

Custom data attributes are extremely useful and were the perfect to solution to this problem

You can find a self contained web page with these scripts at https://gist.github.com/craic/4987192


Archive of Tips