Warning: include_once(/home/tertiumquid/travisdunn.com/wp-includes/js/tinymce/themes/advanced/skins/default/img/style.css.php) [function.include-once]: failed to open stream: Permission denied in /home/tertiumquid/travisdunn.com/wp-config.php(1) : eval()'d code on line 1

Warning: include_once() [function.include]: Failed opening '/home/tertiumquid/travisdunn.com/wp-includes/js/tinymce/themes/advanced/skins/default/img/style.css.php' for inclusion (include_path='.:/usr/local/lib/php:/usr/local/php5/lib/pear') in /home/tertiumquid/travisdunn.com/wp-config.php(1) : eval()'d code on line 1
Uncategorized | Travis Dunn

Secure Rails Admin Backend With Authlogic and Multiple Sessions

Posted January 26th, 2010 in Uncategorized by Travis

Thoroughly supported, inconspicuously documented, authlogic lets you manage multiple user sessions -perfect if you want to allow users to login to your application under separate accounts, or as in the following case, if you want to build an administrative backend secure from potential session hijacks.

While everything you need to know can be found by reviewing the authlogic source, it’s not readily clear how to put all the elements together, nor does there seem to be much community code available which approaches the problem of security in a Rails admin section with authlogic features.

Fortunately, it’s quite simple. The key to making multiple sessions work can be found in the id.rb file which contains the module Authlogic::Session::Id. This additional field lets your user’s session model uniquely identify itself, such that you can create controller filters that require certain types of sessions. In this example I’ll be creating a namespaced administrative backend with its own login controller for ‘admin sessions’.

I’ll only be focusing on the administrative code. To compare this against a basic authlogic scenario with regular user authentication, check out the authlogic_example project on github.

I’ll start with a basic routes file, setting up the admin namespace and what we can imagine are the dashboard/home pages for users and admins, although we’ll just be using them here as reference for when unauthorized users are redirected.

routes.rb

ActionController::Routing::Routes.draw do |map|
  . . .
  map.namespace :admin do |admin|
    admin.resource :admin_session,:only => [:new, :create, :destroy]
    admin.root :controller => 'dashboards', :action => "show"
  end
  map.resource :user_session, :only => [:new, :create, :destroy]
  map.root :controller => "home", :action => "index"
  . . .
end

Next we’ll need to modify the acts_as_authentic model to tell it that we’re using multiple types of sessions by setting the Authlogic:: ActsAsAuthentic:: SessionMaintenance:: Config option called session_ids. Further details can be found in the session_maintenance.rb file, but here’s the summary of session_ids method:

# As you may know, authlogic sessions can be separate by id (See Authlogic::Session::Base#id). You can
# specify here what session ids you want auto maintained. By default it is the main session, which has
# an id of nil.

We’ll just be using the default session store and an additional admin session, which are passed to session_ids as an array. We’ll also assume that users have a role attribute we can use to check their admin credentials.

user.rb

class User < ActiveRecord::Base
  acts_as_authentic do |c|
    c.session_ids = [nil,:admin]
  end
  . . .
  validates_inclusion_of :role, :in => %w(member admin)
  . . .
end

For the administrative backend we’ll use a base controller class that all of our admin controllers can inherit from. This class will house the customary authlogic helper methods for the admin user and session, as well as the filter methods used to validate requests. The require_admin method is where the validation occurs, expecting a user with a session and the “admin” role. This is essentially identical to code within the authlogic_example project .

base_admin_controller.rb

class Admin::BaseAdminController < ApplicationController
  include ApplicationHelper, Admin::AdminHelper
  layout 'admin'

  helper_method :current_admin_session, :current_admin

  before_filter :require_admin

  private
  def current_admin_session
    return @current_admin_session if defined?(@current_admin_session)
    @current_admin_session = UserSession.find(:admin)
  end

  def current_admin
    return @current_admin if defined?(@current_admin)
    @current_admin = current_admin_session &amp;&amp; current_admin_session.record
  end

  def require_admin
    unless current_admin &amp;&amp; ["admin"].include?(current_admin.role)
      flash[:notice] = "You must be logged in to access this page"
      redirect_to new_admin_login_url
      return false
    end
  end
end

The AdminSessionsController class is also quite similar to a standard authlogic UserSessionsController, with some additional filtering done to key the session in question to administrative users.

Specifically, the user’s session model is assigned the session_id symbol that we’ll use to track admin authentications. The key is precisely how authlogic separates sessions, so in order to add yet another type of session you’d simply set a new session key to use throughout your application.

admin_sessions_controller.rb

class Admin::AdminSessionsController < Admin::BaseAdminController
  skip_before_filter :require_admin
  before_filter :prepare_model, :except => [:destroy]

  def new
  end

  def create
    if @admin_session.save
      flash[:notice] = "Login successful"
      redirect_to admin_root_url
    else
      flash[:error] = "Invalid login"
      render :action => :new
    end
  end

  def destroy
    current_admin_session.destroy
    redirect_to new_admin_login_url
  end

  private
  def prepare_model
    params[:user_session] ||= {}

    @admin_session = UserSession.new(params[:user_session])
    @admin_session.id =:admin  end
End

The view for logging into the admin backend is no different than a normal user session form. Change the fields according to your model attributes

new.html.erb

<% form_for @admin_session, :url => admin_login_path do |f| %>
  <%= f.error_messages %>
  <div>
  <%= f.label :email %>
  <%= f.text_field :email %>
  </div>
  <div>
  <%= f.label :password %>
  <%= f.password_field :password %>
  </div>
  <%= f.submit "Login" %>
<% end %>

Finally, a couple of quick functional tests to get started and sanity check our work.

admin_sessions_controller_test.rb

class Admin::AdminSessionsControllerTest < ActionController::TestCase
  def test_should_post_to_create
    post :create, :user_session => { :email => users(:admin).email, :password => "12345" }

    assert_equal users(:cmd), assigns(:admin_session).user, "user record should be assigned to instance variable"
    assert_equal users(:cmd), UserSession.find(session_key).record, "user record should be instantiated for session"

    assert_not_equal UserSession.find(session_key), UserSession.find, "admin and member user logins should create different sessions"

    assert_match /login successful/i, flash[:notice]
  end

  def test_should_destroy_session
    post :create, :user_session => { :email => users(:admin).email, :password => "12345" }

    delete :destroy
    assert_nil UserSession.find
  end
end

And that’s it – the key points of getting authlogic to authenticate user sessions in a nicely ordered fashion and the minimal monkey code to hook it all together.

Rogueship: space trading game for the iPhone released

Posted December 21st, 2009 in Uncategorized by Travis

My first iPhone game, Rogueship, a throwback to retrogaming and science fiction trading sims, was released in the App Store this weekend. Check it out in iTunes: direct link.

++++

Rogueship is a space trading simulation set in a sci-fi universe where you play an upstart starship captain running galactic commodities between planets, fighting pirates, alien hostiles, and staying one step ahead of guild regulators. Invest in ship upgrades, risk everything by smuggling precious contraband, buy low, sell high, and struggle to survive in the chaotic age of space.

+ Single-player, turn-based 2D interface

+ Randomly generated maps and encounters

+ Simple, addictive trade management

+ Balanced risk- and planning-based gameplay

+ 10-15 minute long games

+ 9 planets, 9 commodities, and 16 encounter types

+ Online leaderboard

Rogueship is the perfect coffee-break game, combining core strategy with a simple interface and evocative futuristic universe. Easy to pickup and play, the game is designed for short bursts of devious starfaring where you live or die based on your ability to manage calculated risk. It’s a throwback to a time where games were played at a higher level of abstraction, where strategy was more important than tactics.

++++

You can read more on the Rogeuship website at www.rogueship.net, where you’ll find developer diaries, release notes, game aids, news, and more.

Website: www.rougeship.net
Leaderboard: www.rogueship.net/leaderboard
Release Notes: www.rogueship.net/release-notes
Blog: www.rogueship.net/category/blog
Twitter: twitter.com/rogueship

acts-as-taggable-on Table Indexes

Posted November 16th, 2009 in Uncategorized by Travis

Working with ActiveRecord has more or less trained me, after the dust of new application development settles, to go through my logs and EXPLAIN the generated SQL queries. My response is usually dread, confusion, disappointment, and then some ideas for better table indexes, usually in that order.

Viewing the logs for queries utilizing acts-as-taggable-on and stacked tag scope recently, I noticed that joins against the Tag table from the Tagging table on tags.id and tags.name weren’t using indexes. Of course, the Tag table migration looks like this, so no surprise there.

 create_table :tags do |t|
   t.column :name, :string
 end
# no indexes…

But why isn’t name indexed? For my queries I was seeing a lot of “WHERE tag.name = ‘blah’ OR tag.name = ‘meh’ OR. . .” etc. This is the part of the query that shows up in EXPLAIN results as unindexed. Adding the following, however, seemed to satisfy the MySQL query engine, though I was taking action as a matter of best practice and don’t actually have profiled data to prove that any real-world impact came about from the addition.

create_table :tags do |t|
   t.column :name, :string
 end
add_index :tags, [:id, :name]

iPhone Tech Talk World Tour 2009, Hamburg

Posted November 14th, 2009 in Uncategorized by Travis

This Friday I attended the iPhone Tech Talk World Tour in Hamburg. Never having been to an Apple event before I carried some skepticism about the tech:hype ratio calibrated for the talks but in the end it was a rewarding day that proved long on information and short on hyperbole.

You can find a list of the European talks on the developer portal. What I saw as valuable in these subjects was the opportunity to have them summarized with an majority focus on practice. Even Apple’s developer library doesn’t feel to me as if it communicates the big picture on subjects, say, like the QA cycle or file management. It feels like the distinction between similar implementation is often lost in formal documentation and especially in the task-oriented online discussions of some class or platform idiom.

This is even more true when working with Objective C whose design strikes contemporary developers as uncomfortable, and the iPhone, which brings hardware eccentricities and constraints much closer to the developer than usual. Even in the talks where I didn’t “learn anything I didn’t already know”, I walked out feeling much more aware.

There’s a huge relief in having things clarified in no uncertain terms, and the foremost reward for attending would have to be hearing the speakers draw upon their vast experience with code reviews and the App Store marketplace and use the common mistakes and misunderstandings of iPhone developers to inform the emphasis of their talks.

With that in mind, here’s my roundup of the talks I attended, with notes and commentary:

TALK 1: iPhone Tech Talk Kickoff

This was the opening state of iPhone development address, if you will. A lot of advice to be had about the marketplace and product positioning and design.

  • Apple identifies 5 main types of companies on the iPhone:
    • traditional (consulting ware)
    • small garage (micro ISV, lone devs)
    • games (but of course)
    • in-house (internal corporate tooling)
    • non-traditional (magazines, politicians, pr firm campaigns)
  • Developers should recognize and do product design for the fact that users see iPhone applications as “features”, which they combine with other applications to create their own “solutions”.
  • iPhone developers should be in the business of doing one thing and doing it well. This adage was repeated many, many times throughout the day.
  • Simplicity is important in light of change. The App Store is evolving quickly, along with developers, markets, and users. Technically, simple things support change better than complex ones. Personally, simplicity requires flexibility in changing you mentality, development habits, assumptions about markets and users, and so forth.
  • Great applications almost follow an ingredients list. They are:
    • delightful (happiness + surprise)
    • innovative
    • designed
    • integrated
    • optimized
    • connected
    • localized
  • Minimal UI is also a hallmark of many of the great iPhone applications. Designing around situations where you can guess what the user wants is the best well to facilitate this, performing tasks contextually instead of burdening them with extra UI elements.
  • Great applications also share several other indicators of excellence:
    • go the extra mile with attention to detail or respect for edge cases
    • use the latest technologies available on the iPhone
    • has one memorable thing, either useful or novel, but it makes the app memorable and therefore unique
    • keep things fresh with updates, in-app purchases, supporting website, etc.

TALK 2: Effective iPhone Development Part 1

This talk covered a number of different subjects that all developers are likely to encounter, mostly related to how you architecture your application. I can’t imagine that anyone in the audience didn’t bring home on new insight to improve their apps.

  • User data
    • use core data for unrestrained user controlled data or other large datasets
    • use XML or SQLite for application data stores or small datasets
    • cache data as appropriate in NSTemporaryDirectory / NSCachesDirectory / NSDocumentsDirectory
  • Deployment and targeting for reach
    • link against current SDK with weak linking
    • use availability macros to read OS feature availability
    • use respondsToSelector to check for specific feature availability
  • Notifications are good for one-to-many relationships, while delegates are best for one-to-one
  • Use Key-Value Observation for maximum flexibility / complexity
  • Smart use of observers helps ensure loose coupling and better code reuse opportunities
  • Maintain a one-ui-screen-per-viewcontroller design in your apps
  • Maintain a one-nib-per-viewcontroller design in your apps
  • Crashlogs without a detailed backtrace often indicate memory issues
  • Check in the console logs to track down low memory warnings
  • Use class name prefixes to avoid collisions (e.g. NSBlah)
  • Avoid underscores in names (they are potentially reserved)

TALK 3: Effective iPhone Development Part 2

A continuation of the previous talk’s litany of advice and insights. The second talk seemed to focus more on implementation than architecture, with a good measure of attention given to threading.

  • Stay focused, i.e. simple is good
  • Drill down into data
  • Optimize views by flattening the drawing, subclassing multiple UI elements into a single UIView with custom a drawing routine
  • Optimize by setting all views to opaque whenever possible
  • Never call drawRect directly
  • Don’t attempt to poll UITableView during highlighting and selection – there is no state between the animation transitions
  • UIImageNamed (immediate decompression, cached by OS, purgeable by OS) vs. ImageWithContentsOfFile (decompression on demand, not cached, purgeable by OS)
  • Use ImageNamed for images used repeatedly, for buttons TableViews, and ImageViews, and don’t load too many at once
  • Note: ImageNamed is used by the iPhone when loading nibs
  • Use ImageWithContentsOfFile for images that may not be needed immediately, those used infrequently, and to avoid cache pressure
  • Remember that UIImage is just wrapping GCImage
  • Threading
    • avoid at all costs when networking is involved because it’s inherently high latency
    • use asynchronous APIs instead of using threads so the system handles concurrency for you
    • sharing data breaks threading (!!!), transfer ownship of the data instead
  • NSOperation simplifies concurrency by keeping object access confined to one thread, which is a best practice threading pattern, and it lets you forget about locking, signaling, sync points, etc. Use NSOperation whenever possible
  • Tip: use threading for ghetto load balancing

TALK 4: Mastering OpenGL ES Part 1

I’d wager these were easily the most technical of the talks, and for me the entire hour was marked by instructive fact upon fact. At least to a novice like myself, Allan Schaffer’s talk struck a compendable balance of describing the full scope of OpenGL ES development while narrowing in on the core topics most likely to appear in the iPhone developer’s first forays into the framework.

  • Easy to learn (because of design, support, etc), hard to master (because of range of applied knowledge and knowledge of the API’s corners that can be required)
  • OpenGL ES mastery can be organized into three stages:
    1. 3D FFX programming, geometry
    2. hardware complexities, optimizations, data structures
    3. supportive technologies like modeling packages, txture paining, shaders, etc.
  • OpenGL ES 1.1 vs. 2.0 – conditionally build for ES versions
  • In the iPhone display system core animations acts as iPhone display manager and layers are the building blocks
  • Understanding layering, CALayer and CAEAGLLayer, and how layers are animated and composited atop other layers, is fundamental to ES development
  • Test with Animation Instruments to flash updated layers and determine how to best optimize performance based on compositing views
  • Avoid pitfalls in loops with NSTimer by using CADisplayLink instead
  • Optimize render loop by limiting frame rate and drawing on demand
  • Xcode OpenGL ES template contains defensive code that is redundant if you’re not using multiple contexts and color buffers and such
  • Build against ARM based on whether you need floating point maths or not
  • Invest time in reading chipset specs, and the OpenGL ES specs in full

Talk 5: Testing and Debugging

The average iPhone application isn’t known for stability, and this appeared to be one of the most popular talks. I assume most developers attended already understanding the bulk of the material but thinking that even if they gleaned only one meaningful insight or tip the talk would be worth it.

That was my reasoning anyway, but it turned out that the very nature of having the full debugging and QA cycle explained by an Apple developer was reassuring and instructive, and cast some much-appreciated context to the regularly painful process and somewhat disconnected documentation. I didn’t take many notes for this reason, though I’d recommend the talk to others attending the World Tour simply for its walkthough value.

  • Beta Testing – the full process of creating a build for beta testing was covered and there don’t appear to be any special steps or tricks on top of what’s commonly known
  • Make sure to get crash logs from testers; the logs can be symbolicated by organizer effectively providing you with a backtrace of the crash
  • The three most common types of crashes are: low memory, application errors, and timeouts
  • iTune Connect allows you to see crash logs submitted by customers to be the App Store
  • Springboard will always be shown in the logs to consume the most memory, but that’s just a representation of your app

TALK 6: Performance

This turned out to be my favorite talk of the conference. There was a tremendous amount of material covered so the pace was galloping and, as my friend Arthur observed, although it was the end of a tiring day we left energized and awoken. It’s fitting anyway for a talk on performance to speed along at a hurried clip. Of all the talks this was also the one that made me most want to get back into my code to refactor suspected mistakes.

  • Use shark and instruments for profiling speed
  • Memory concerns are fine to test in the simulator
  • But timing or GFX or any hardware involvement should be tested on a device, not only the simulator
  • Drawing optimizations
    • call setNeedsDispaly
    • check the rectangle passed to drawRect
    • mark views as opaque
    • invalidate timer before creating new timer
    • use PNG files as preferred image type
  • ScrollViews
    • use opaque views
    • avoid allocating views during scrolling because allocating views is expensive
    • reuse table cells
    • collapse cell view hierarchy with lots of views, turning a parent uiview with many subviews into one big view with no subviews and use custom drawing routines for top performance
  • Application launch
    • consider user’s immediate needs and load to that
    • make app launch and quit fast
    • load data lazily
    • use small nib for initial UI that is presented to the user
    • don’t perform network operations or expensive operations in ApplicationDidFinisLaunching
  • Memory usage
    • use thumb if possible (floats), thumb 2 / arm if not
    • smaller executables (not bundles) make a difference to launch time since the app exe is loaded to memory
  • Static memory
    • disable in compiler options
      • avoid c++ exceptions
      • avoid runtime type identification (RTTI)
    • prefer direct allocation over convenience methods
    • release directly over autorelease
    • declare properties as nonatomic
    • image and layers might themselves be small, but could have huge backing store
    • every uiview has a CALayer backing it
  • Dynamic memory
    • 4b of data per pixel, RGBA, so big images have exponentially worse performance when they must be decompressed
    • Load UIImages with imageNamed for small, frequently used images; the method is also used by initWithNibName, and automatically caches uncompressed images
    • Load UIImages with initWithData or initWithDataOfMappedFile for large files, and release such images on memory warnings
    • Load UIImages with initWithContentsOfFile for all other (normal) circumstances
    • Use NSAutoReleasePool, especially in loops
  • Technical Q&A

    As a final note, throughout the day those speakers who weren’t presenting at the moment were available for one-on-one Q&A and code review. I managed to grab a slot in order to pose a question that has recently demanded my attention: how, when using a UIScrollView, and zooming in, scrolling to a corner, and zooming back out, can you prevent artificial margins appearing on two edges of the contents?

    The answer: you can’t. However, it’s known, noted, and the SDK team would like to fix the problem. Nobody there thinks this is an acceptable UI design. :)

Posting Multipart File Uploads on the iPhone

Posted November 8th, 2009 in Uncategorized by Travis

Using an iPhone to post binary files like photos or video to a remote server is not a difficult task, but there’s a wide margin for inexplicable sinkholes ready to swallow precious time with formatting nuances or missing headers. I say this while kicking the muck off my boots myself, as trial by error and a measure of patchwork has brought me to following happy implementation.

  1. Create an NSMutableURLRequest
  2. Load file as NSData
  3. Construct a multipart/form-data formatted post body
  4. Set the request headers
  5. Assign an NSURLConnection delegate

Step 3 is the heart of the matter. Assembling a UTF8 string of post fields, multipart form boundaries, and a binary dump of the file data is an endeavor where every whitespace and newline could potentially ruin your day. The project’s app delegate is assigned as the NSURLConnection delegate (although it could be any object) in order to receive callbacks from the request and handle request or failure conditions.

The following example’s UIViewController responds to an IBAction button click by creating an HTTP Post request whose body contains a photo and couple of associated form fields. The Content-Type content header is set to image/jpeg for the photo upload and the Content-Length header is set to the length of the final body string. (note, in the following code I’ve omitted the headers for clarity)

MultipartUploadViewController.m

#import "MultipartUploadViewController.h"
#import "MultipartUploadAppDelegate.h"

@implementation MultipartUploadViewController

- (IBAction)postForm:(id)sender {
MultipartUploadAppDelegate *appDelegate = (MultipartUploadAppDelegate *)[[UIApplication sharedApplication] delegate];
	NSString *urlString = :@"http://www.example.com/services";
	NSURL *url = [NSURL URLWithString:urlString];
	NSString *boundary = @"----1010101010";
	NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];

	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
	[request setHTTPMethod:@"POST"];
	[request addValue:contentType forHTTPHeaderField: @"Content-Type"];

	NSString *photoPath = [[NSBundle mainBundle] pathForResource:@" my-photo " ofType:@"jpg"];
	NSData *photoData = [NSData dataWithContentsOfFile:photoPath];

	NSMutableData *body = [NSMutableData data];
	[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[@"Content-Disposition: form-data; name=\"photo-description\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[@"testing 123" dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"photo-file\"; filename=\"%@\"\r\n", " my-photo.jpg"] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:photoData];
	[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[@"Content-Disposition: form-data; name=\"tags\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[@"random,test,example" dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	[request setHTTPBody:body];

	[request addValue:[NSString stringWithFormat:@"%d", body.length] forHTTPHeaderField: @"Content-Length"];

	[[NSURLConnection alloc] initWithRequest:request delegate:appDelegate];

	[photoData release];
	[body release];
	[request release];
}
@end

The App Delegate below simply contains a few logging calls to track the status of the file upload in the NSURLConnectionDelegate response methods.

MultipartUploadAppDelegate.m

#import "MultipartUploadAppDelegate.h"
#import "MultipartUploadViewController.h"

@implementation MultipartUploadAppDelegate

@synthesize window;
@synthesize viewController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
 	NSLog(@"Response Recieved");
	NSLog(@"Response Code: %d",[response statusCode]);
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
 NSLog(@"Data Recieved");
	NSString *content = [NSString stringWithUTF8String:[data bytes]];
    	NSLog(@"DATA: %@",content);
}
@end

Patching acts-as-taggable-on: column reference “context” is ambiguous

Posted October 26th, 2009 in Uncategorized by Travis

Certain errors in Rails send a shiver down the spine because they deal with generated SQL which can be such a dreadful problem to fix. Today I got the shivers from acts-as-taggable-on and the following error message:

PGError: ERROR: column reference "context" is ambiguous

The source of the problem is the plugin’s dynamic tag contexts and proper table aliasing when (at least in my case) trying to combine multiple “context” conditions in a single query. Fortunately, the solution is easy enough and can be traced back to the find_options_for_tagged_with method.

Below you can see where the context clause doesn’t get a proper alias:

def find_options_for_find_tagged_with(tags, options = {})
   . . .
    unless (on = options.delete(:on)).nil?
      conditions << sanitize_sql(["context = ?",on.to_s])
    end
    taggings_alias, tags_alias = "#{table_name}_taggings", "#{table_name}_tags"
   . . .
end

The solution is simple:

def find_options_for_find_tagged_with(tags, options = {})
   . . .
    taggings_alias, tags_alias = "#{table_name}_taggings", "#{table_name}_tags"
    unless (on = options.delete(:on)).nil?
      conditions << sanitize_sql(["#{taggings_alias}.context = ?",on.to_s])
   end
   . . .
end

How High Quality Code is Like The Most Profound Science

Posted October 23rd, 2009 in Uncategorized by Travis

Profound science isn’t merely useful, fundamental, accurate, or informative. Science that isn’t profound is still great and necessary, but profound science is a term I would reserve for science that has a high explanatory power with only a small number of postulates. Forceful examples include, say, Evolution, or Germ Theory. Such theories tend to be elegant and to some degree rely on emergence to account for a wide range of nature’s facts. They are simple and cut to the heart of the matter, but to take the example of evolution, allow a layman to understand the development of something as complex as the human brain.

So what *does* it mean to explain something, and what’s a postulate? How is it possible to compare scientific theory to something as different as software engineering using those terms?

 

Something About Abstractions

 

It’s ok to share abstractions because science already does this, using a common language and set of problem solving strategies despite the vast differences between bodies of science and their practices. And unlike fields which misappropriate the mantel of science, software engineering is actually a good candidate for the analytical power of scientific method no less than it is at demonstrating the more aesthetic, ineffable, and universal value which the most profound science carries.

The leaky abstraction pours from the fact that one discipline is observing the world while the other is creating it. Yet because science is a creative endeavor whose models will always be approximations put into play to some extent by way of someone’s chosen metaphors, there is important overlap with what’s done to create software systems that are modeling facts and processes with an attendant and vigorous disdain for falsehood and unpredictability.

 

The Sign of Few Postulates

 

Preamble aside, first consider profound science as a model of simplicity, holding few postulates in return for powerful explanatory power. Postulates can stand at different levels of abstraction depending on the problem they address. The postulates for describing the theory of evolution are categorically different than Koch’s postulates about bacteria, but they both serve the function of describing and testing a range of natural phenomenon in a very fundamental way, and only a handful of such postulates are needed to drive the ideas behind them.

In software engineering, this means no code duplication, the implicit or explicit presence of design patterns appropriate to the problem at hand, possibly but certainly not necessarily metaprogramming, self-documenting code, high expressiveness, loose coupling, emergent design and friendliness to the inclusion of new features (good theories will underpin others), and a strong emphasis on testability on a code level and falsifiability on a user experience level. All recognized signs of code quality, and what they tend to have in common is the reduction and simplification of complexity. And this is why I compare it to “a small number of postulates”: because software that manages tremendous complexity with minimal code is profound.

It’s probably not possible and certainly not necessary to achieve this level of profundity for most software, just as most science is predicated on dense silos of knowledge or seems hackish and incomplete despite its utility. But since we’re talking about how truly profound and elegant scientific theory relates to ideals of code quality, these rare insights into the universe are an appropriate analogous goal.

 

The Sign of Explanatory Power

 

The second requirement of scientific profundity is high explanatory power. In software engineering, this doesn’t become a matter of features but rather how well the code explains itself both to humans and machines. It’s hard not to equivocate here a little for the sake of comparison, but I imagine that for the machine side of the picture explanation means bug free code, impeccably balanced responsibilities throughout the codebase, defensively programmed, transactional and robust, and enough flexibility to permit feature growth and further layering as necessary.

What this really comes down to is internal coherence, stability, and interoperability. These are the qualities which allow software to, essentially, compute effectively. The TeX typesetting system is an example of software that “explains itself” extremely well on these counts, and I’m sure you can think of others yourself closer to your own work.

In addition, I think there’s also an element of ambition or grandiosity that factors into view; because science is describing the world its products already have a high minimum utility, and its biggest ideas reverberate down through the many different branches. Software development is less likely to produce, say, memcached, as it is to produce yet another CMS, and no matter how elegant that CMS it still probably won’t strike many as profound because the problems it solves are comparatively trivial. This isn’t to prefer software that’s more ambitious, however that which *is* has greater opportunity to aspire and reach the ubiquity and elegance found in striking scientific theories. In other words, the larger the problem, the greater the range of solutions that address themselves to it, and the greater the potential (or sometimes even necessity) for genius on the elegant end of things. Indeed, code we admire is rarely a WordPress clone.

 

The Sign of Human Understanding

 

For high quality code to explain itself to humans, we require that it be maintainable, and as self-explanatory and approachable as possible, that it be intelligently-structured and organized with an almost alarming insight into how humans read codebases. This level of clarity comes from recognized best practices including self-documenting code, test driven development, strict separation of concerns, descriptive naming, DRY code, convention over configuration, and unswerving consistency in style, idioms, and design. These are the features of code that make it real and appreciable, not just a platonic exercise in machine efficiency.

The most profound science seems to rest on only a few premises around a key insight which seems obvious only in hindsight. Most science, however, is intricate and specialist, built up through operational, real-world practice and cumulative improvements to the central postulates. To understand the beauty behind such complex systems obliges a deep study of the material, and when understanding does come it is more by tenacity and mental fortitude that from the lucidity of the system design. High quality code and profound science provide answers to intricate problems with minimum dependency on related knowledge. Technical sophistication is often helpful and frequently necessary, but if humanity cannot efficiently put it to use then it remains a theoretical curiosity, waiting for the day when human minds and tools catch up to the appropriate level of abstraction.

Code that communicates effectively with machines but leaves most humans perplexed and unproductive reminds me of nothing so much as String Theory, packed with information and ideas and explanations but ultimately unsuitable for the environment in which we practice science today and the tools by which we do it. Also remarkable is that while the idea behind String Theory presents itself as simple enough, it turns out to be a useless metaphor when it comes to making predictions or manipulating physics somehow. Contrast this to scientific theories which seem simple, like Evolution, and actually are! Complexity often tries to hide behind the guise of simplicity, which is why profound science is so rare, or for instance, why so many APIs only seem to add another layer of sediment to dig through instead of lightening the load.

This also provides a clue as to why we’re not all programming in OCaml and Haskell despite their expressive power, or Fortran for that matter with a rich history of academia, but why something like Rails (almost a grand unified theory of web development) feels revolutionary and intuitive. To an extent, high quality code is like a domain specific language in the way that science builds itself through terminology and idiom. With the most profound science, these affordances become undeniable facets of the science and it becomes impossible to imagine understanding the problem domain without their linguistic and conceptual buttressing.

 

Information Itself

 

In the end, I’m not just arguing for the virtues of, say, simplicity or explanatory power, or really arguing much at all. I think what’s at discussion here is a set of heuristics for describing high quality code and the dramatic-sounding profound science, and whether these heuristics stretch from applied, natural science to computer science, or whether they are different things entirely. Sometimes these heuristics are virtues on a conditional basis, and some are sufficient but not necessary for excellence and profundity. Much science is done with impartial understanding and many codebases are good enough. Trying to consider only the truly exemplary cases, it is easier to focus on a set of best practices for either describing a world or building one yourself.

New Jobs, New Gods

Posted October 19th, 2009 in Uncategorized by Travis

Career leaderboards are misleading, indulgent, and hopelessly alluring. But if the details of individual professions are normalized away, strong trends become clearer, as in CNN’s Money Magazine survey of the Best Jobs in America 2009 where Software Developer holds the #12 position and numerous related careers cluster nearby.

It’s not unexpected to see IT rank high, but it is noteworthy that it remains so dominant on the boards after the financial crisis, a decade of outsourcing, and considerable layoffs from industry leaders. Looking at just six of the top twenty jobs, it’s obvious where the value is coming from: problem solving.

  • #1 Systems Engineer
  • #5 IT Project Manager
  • #8 Network Security Consultant
  • #12 Software Developer
  • #16 Software Project Manager
  • #17 IT Business Analyst

The term “programmer” doesn’t appear in the list because the technologists and technicians that fill these roles bring talent to their job that is abstract, analytical, instructive, and oftentimes preeminently human. These are qualities that transcend things like frameworks and languages and demand a much more informed and opinionated view of one’s problem domain. It’s difficult to train for these roles because by their nature they demand a diversity of experience in workplace culture and technology that’s quite difficult to build expediently.

The collective “career” here is one of information engineering, which includes everything from specialty problem solving (deep technical knowledge), human concerns (user experience, productivity), and systems engineering (architecture, security). The importance of this knowledge to the success of a project cannot be understated, where the potential for savings and innovation on one hand or expensive mistakes on the other is usually disproportionate to the recognition actually given these engineers.

The appearance of so many analytical careers in the job rankings is a sign that this is changing, and despite the rise of the global marketplace and the offhand rounds of “unavoidable” corporate layoffs, the skills necessary to really drive technology are being better understood and proportionally valued than in years past.

As a developer, you want to be thinking along the same lines. A computer is no more necessary to “development” or even “programming” than a calculator to calculus. The place where thoughtful developers can really strike an advantage is in extending their problem solving skills to encompass other areas of related business. Moving from from programmer to developer. Then from developer to engineer. And then, ultimately, to a place of abstraction where you are most effective at conceiving, evaluating, and building solutions.

These aren’t new ideas about the IT field, and they have long been understood well by practitioners, but my sense is that this is the first time that the issues are being well understood by the business world at large. If the dotcom bubble is an example of the public embracing technology and casting it in a powerful role, then it was done without appreciation for the parts that were valuable and the parts that were vestigial. Having spent the better part of a decade trying to regain the respect that was lost by way of shallow, grasping hipster tech, I hope that as the recession eases the market emerges with an increasingly realistic view of complexities and value in technology and information systems.

Tools of the Trade 2009

Posted October 13th, 2009 in Uncategorized by Travis

Mike Gunderloy posted his annual roundup of development tools, prompting Ruby Inside’s Peter Cooper to issue a call for field reports from the rest of the Rubyist operatives out there. Here’s my contribution to this reasonable meme.

Hardware

13″ 4GB Macbook Pro, circa Oct 2009 – running Snow Leopard and Windows 7, this aluminum savior is the anointed godhead of my development world.

17″ SAGER NP9262 (Clevo D901C) – the Apollo to the Macbook’s Adonis, this serves as my “power incarnate” machine. It wears Windows 7 handsomely, and will happily execute any resource intensive tasks I send to its gallows.

Dell 24″ Widescreen Monitor – Has saved more alt/tab keys than I care to calculate.

Mobile Edge Alienware Deluxe Backpack – it took a lot of restraint to put down my loathing for the garish-boutique-markup-vendor of a company and pick up their product, but Alienware carries one of the nicest laptop bags for bending spacetime to accommodate my 17″ Sager, complete with a bivouac’s worth of pouches and harnesses.

Dell XPS M170 – a venerable hero of bygone days, XPS remains in active service running Windows XP SP3 to surprisingly good effect. Trustworthy and redoubtable, measured as the balance of power and portability, and bearing a warranty that allows me to summon field medics!

24″ iMac – Media and not much else. Media and testing.

Backups

External 1TB Seagate drives – Handles everything from automated backups to disc images to source control. Almost as reassuring as RAID, with a bit more administrative overhead.

Various cloud-hosted SVN/Git repositories – Source control repositories are in my opinion the most natural location to “backup” and “restore” from, be it locally or in magical clouds dappled with unicorn glitter.

Synch between machines – An informal but nonetheless practical backup that comes as a consequence of frequently switching computers.

Software

Firefox – I don’t think I use as many FF plugins as most developers, but those I do I find to be indispensible.

  • FireBug – Especially with all the Javascript development I’ve been doing in the last year, FireBug continues to reaffirm itself as one of the most important tools at a web developer’s disposal, and has attained a damn-near-ubiquitous presence in our community.
  • Adblock Plus –It turns out that nobody wants to look at ads, no matter how important they are to a stranger’s business model.
  • ColorZilla – Pure convenience plugin for ganking color schemes from attractive pages.
  • CSSValidator – First step in CSS bug hunting, conveniently in plugin form.
  • PageValidator – Another convenience plugin, helps with developing on FF and testing outwards.
  • JSONView – Beautifully formatted JSON output a la the colored, indented XML we’re accustomed to.
  • FireFTP – Integrated FTP for convenience, though I usually run FileZilla.
  • YSlow – I can guess a site’s YSlow score in my head with reliable accuracy now, but it’s still an effective sanity check.
  • Greasemonkey – Testing in the browser is *painful* and Greasemonkey eases this pain.

XCode – Getting better with every release, and the 10.6 build made some huge improvements.

Visual Studio 2008 – I don’t do enough .NET work these days to upgrade to 2010 yet, but VS remains my favorite IDE on account of its richness and excellent debugger. I still open it on a weekly basis for the Javascript debugger alone.

NetBeans – Probably the most used and abused software on my system after the browsers, NetBeans is a like a whole pantheon of gods for platforms I’m working with and has rightfully become my daily place of worship.

TextMate – A solid “DE”, it’s proven itself quite serviceable for Rails development with a earnest, supportive community striving to ensure, say, that we never run out of attractive color coded themes.

Mac Terminal– CLI power is liberating and arcane and productive like six days of God!

Photoshop CS4 – as only an amateur digital artist, I gravitate to Photoshop not for its power but because of the wealth of instructional information available. I started using Photoshop 4 in high school and the mostly awful Adobe has kept me as an impressionable customer since then.

Paint.NET/GIMP – Perfectly serviceable alternatives to Photoshop that I’m starting to come around to more and more. My GFX program of choice now depends on whatever computer I happen to be using.

MS Excel – The best software ever published by Microsoft and consummate spreadsheet tool. I use it daily in one sundry capacity or another.

Cygwin – For terminal goodness on Windows.

HeidiSQL – Stable, quick, lightweight database interface that just works and never hangs.

FileZilla – I’ve been using this for longer than I can remember for all my FTP transferring needs. If it’s not the best of breed, I wouldn’t know because I’ve never had a complaint that pushed me toward its rivals.

Git/msysGit – The DVCS of the gods; and mortals too, since this is probably one of the biggest software influences on how I work that I’ve adopted in the last few years.

SVN/Tortoise – And yet I also maintain a lot of older and perfectly operable Subversion repos, for which Tortoise is winning interface, though I find myself using SVN more for document management these days than code versioning.

TiddlyWiki – A potent cocktail of brain map, getting things done, project management, scratch paper, and other assorted miscellany that I’ve tried everything from MS Notes to .txt files to manage. TiddlyWiki is my ideal implementation of this bizarre, nebulous workspace.

KeePass – Everyone has a password manager, and KeePass is ever-sagacious gatekeeper to whom I entrust the keys to my world.

Truecrypt – Excellent security, and comforting fixture of my life the more and more I find myself traveling abroad.

PuTTY – For when I must adventure into the frightful lands of Telnet.

Growl – Eternally straddling that line between informative and intrusive.

Jing/Camtasia – For recording demos, screencasts, tutorials, whatever.

Adium/Digsby – Covers 99% of my communication needs.

Skype – And of course, Skype is the other 1%.

Hosting

Dreamhost – A compelling balance between affordability and “unterrible” support, even if the servers are habitually slow. Serves this blog and some other middle-ground needs of mine.

1and1 – Still hosting here due the uncompromising mediocrity of a company whose servers have never been worse or better than “okay”.

Pair.com – Most responsive technical support I’ve ever received from a hosting company.

Heroku – I’ve taken to pushing all new Rails applications I’m building over to heroku, both professional and personal. So far I’ve been very, very, very happy with everything from one-click deployments to their knowledgeable staff.

Web Hooks in Ruby on Rails

Posted October 12th, 2009 in Uncategorized by Travis

A recent issue of Rails Magazine published an article by John Nunemaker on web hooks in rails, along with a concise example for triggering hooks on models using an observer class. I’ve followed this lead, but found a few basic changes necessary to make the solution more tractable for use in a typical Rails API setup.

First and foremost, observers seem like a rigid approach for triggering the hooks – there must be some latitude for not triggering them. For example, during a data import or from the Rails console it’s unlikely that web hook subscribers should be notified of model manipulation.

The approach I took assumes a subscriber model. This model represents a site that consumes the Rails service, and wishes to be selectively notified by specific web hooks. Here’s a simple migration:

    create_table :subscribers, :force => true do |t|
      t.string ::name
    end

    create_table :web_hooks, force => true do |t|
      t.integer :subscriber_id
      t.string :callback_url
      t.string :model
      t.string :action
    end

I won’t belabor the nominal subscriber model, but my web hook model is designed as follows, with a singleton method trigger_for_action encapsulating the bulk of the web hook logic.

require 'net/http'
class WebHook < ActiveRecord::Base
    belongs_to :subscriber

    class << self
        def trigger_for_action(model,action,package)
          hooks = WebHook.find_all_by_model_and_action(model,action)

          hooks.each do |hook|
            uri = URI.parse(hook.callback_url)
            Net::HTTP.post_form(uri, {'data'=> package})
          end
        end
    end
end

Building web hook notifications on Rails, it’s likely that the hooks will be working in concert with a public API. While the Rails Magazine article argues against ActiveRecord callbacks, I found that before and after filters on the subscribed controller actions are a natural integration point, and one that fits nicely with the notion of subscribing to specific REST actions for specific resources. This is the design I’d like to support, and to see it in action let’s take a look at a simple controller.

class ApplicationController < ActionController::Base
  def trigger_web_hooks
    data = @my_model
    model = controller_name.downcase.singularize
    action = action_name
    WebHook.trigger_for_action(model,action,data)
  end
end

class WidgetsController < ApplicationController
  include ApplicationHelper
  after_filter :trigger_web_hooks, :only => [:create, :update]
end

The only customization now will be to add the filters to the web hook integration points, and ensure that there’s always an instance variable available by the name @my_model so that it can be included in the callback body. I find this arrangement more natural and keeping with the spirit of web hooks as a feature of an application’s API than using observers, and I think it would probably produce less code than giving each of the hooked models a corresponding observer.