Archive for the 'Uncategorized' Category

07
Jan

Take Control of your Field Values with nilify_blanks

If in your data schema most or all of your fields are NULLable (the Rails default in migrations), you may have run into the issue whereby sometimes your fields are blank and sometimes they are NULL, two distinct representations of a “no data” state.  This arises in Rails often because when you submit a form and the user doesn’t fill in a value, the value sent to the database is an empty string, even if you may prefer the field to just remain NULL.

Enter nilify_blanks, my solution to handling this problem generically in your models.  With nilify_blanks you can specify the fields you want “nilified” (or default to all content fields) upon save if the field is blank.  This allows you to regain some consistency in how you represent data in the database.   Use of the plugin is best-explained with some examples:

Basic Examples

  # Checks and converts all fields in the model
  class Post < ActiveRecord::Base
    nilify_blanks
  end

  # Checks and converts only the title and author fields
  class Post < ActiveRecord::Base
    nilify_blanks :o nly => [:author, :title]
  end

  # Checks and converts all fields except for title and author
  class Post < ActiveRecord::Base
    nilify_blanks :except => [:author, :title]
  end

Specifying a Callback
Checking uses an ActiveRecord before_save filter by default, but you can specify a different filter with the :before option. Any filter will work – just first remove the “before_” prefix from the name.

  class Post < ActiveRecord::Base
    nilify_blanks :before => :create
  end

  class Post < ActiveRecord::Before
    nilify_blanks :before => :validation_on_update
  end
05
Jul

Inverting Permission-Based Filtering with named_scope

The addition of named_scope in Rails 2.1 has revealed several elegant approaches for modeling complex problem domains in ActiveRecord.  One I came across recently while working on an app with a somewhat complex permissions system was a permission-based filtering mechanism.  In this case I was dealing with permission for a given user to manage an “office”, while a user could be at one of three permission “levels”, one of which has specific office assignments (or it’s assumed all are manageable if user.can_manage_all_offices is true). Lot’s of necessary conditional logic there.

Now a normal approach to such a task to “show a list of offices that the user can manage” (for a drop-down for an interface perhaps) might be something like this:

# In controller:
if current_user.can_manage_company?
  @offices = Office.find(:all)
elsif current_user.office_access_level? && current_user.can_manage_all_offices?
  @offices.find(:all)
elsif current_user.office_access_level?
  @offices.find(:all, :conditions => {:id => current_user.manageable_offices.map(&:id) })
else
  @offices = []
end

But this approach starts at the user level and, using a lot of conditional logic baked right into places we don’t want, makes different calls to Office, which isn’t very DRY, and certainly not consistent with fat models skinny controllers.  So I considered inverting this approach and instead starting with an office, and asking it what “is manageable by” a given user.  Consider this alternative:

# In office.rb
named_scope :manageable_by, lambda {|user|
  case
  when user.can_manage_company? then {}
  when user.office_access_level? && user.can_manage_all_offices? then {}
  when user.office_access_level? then {:conditions => {:id => user.manageable_offices.map(&:id)}}
  else {:conditions => "1 = 0"}
  end
}

# Then in controller:
@offices = Office.manageable_by(current_user)

This seems much more elegant to me.  I’m in general finding a lot of opportunities for inverting the way I designed something without named_scope to be more model-centric, so this approach helps further the design principle of “fat models, skinny controllers”. Sure you could do this before by defining your own methods and using with_scope, but named_scope just makes it all the more elegant.

Another advantage with using the named scope stuff is that you can chain scopes together. Let’s say that in another controller I want to do the same thing but instead restrict results to active offices only. I can create an “active” named scope that scopes :conditions => {:active => true}, then in the controller simply do this instead:

@offices = Office.manageable_by(current_user).active
28
Jun

Pleasing the JavaScript Download Time Whiners

To me, the benefit of using JavaScript frameworks in an application cannot be overstated.  Though I’m also a fan of server-side frameworks, there is scarcely a reason not to use a client-side framework these days.  Of course the most common complaint against JavaScript frameworks is “bloat” and the long download time.  Funny that the most vocal of those complaining about the frameworks’ download time are those who haven’t even ever used a framework to experience it’s benefits.  The tradeoff of course is a noticeable load hit for some users on slower connections vs. architectural elegance, much higher productivity, more maintainability, and less code in general.  To me in most cases the trade-off is a no-brainer in any sufficiently modern web application, but not to all.

Released recently is the Google Ajax Libraries API which is basically a way of allowing browsers do download only one version of a given framework for all applications using that framework.  Currently most web applications host their own version of a given JavaScript library, which is inefficient across the spectrum of the internet since many sites are using the exact same library.  With Google Ajax Libraries you essentially reference Google’s hosted version of the library and the download hit is only incurred the first time a user visits any site using that framework.  So it’s quite likely that a user going to your site won’t have to download a thing – it’s as if the framework is at that point simply part of the user’s browser.

Of course this only works if it becomes widely used and I sure hope it will.  I’d encourange all developers to start using this in their production environments (development environments should still use local copies for local development:

Google AJAX Libraries API
Rails Plugin for Google AJAX Libraries API

01
Apr

Ruby on Rails is going down! Introducing: Cobol on Cogs:

I am convinced this is the next big thing: Cobol on Cogs.  Definitely the future of web development.  As of today I renounce Ruby on Rails and all it stands for!

19
Mar

JazzToolbox REST API Deployed

Today I deployed a major update to my Jazz object model which implements a full REST web interface that is currently accessible through a web browser. Visit http://www.jazztoolbox.com/ for the RDocs – there are plenty of examples at the bottom of the index file, or you can try this immediately:

http://www.jazztoolbox.com/chords.xml

Some fairly complex relationships can be explored in this manner just using your web browser (displaying XML). Note that I still do not have a whole lot of data in here; all the data is just my personal knowledge of Jazz theory. Eventually I will consult a theory reference and develop the database of jazz more thoroughly.

11
Mar

Object-Oriented Approach to Blank Checking/Defaulting

Something I constantly find myself doing is checking to see if a value is blank, and returning something else if it is, otherwise the object itself:

birthday.blank? ? '0000-00-00' : birthday

I started thinking about how I could possibly eliminate the need for all these ternary operators, and came up with this:

class Object
  def or_if_blank(value)
    self.respond_to?(:blank) && self.blank? ? value : self
  end
end

Now we can do something like this:

birthday.or_if_blank('0000-00-00')

You could do something similar for nil, though a more general Ruby idiom is to just use the || operator, which does not work for blank.

On another note, if any of you are used to appending a “if object.respond_to?(:method)” predicate, check out this technique using try.

25
Feb

Introducing JazzToolbox: A computational model of Jazz Theory…

As a (wannabe) Jazz pianist, I’ve always had a strong interest in Jazz theory not only from a practical you-need-this-to-play standpoint but also a theoretical standpoint. At it’s core, music theory is all about a 0 – 11 number system where each number represents a pitch, with the added complication of letters (which makes Eb theoretically different from D#). Everything in music is based on this basic number system: scales and chords are simply sequences of these numbers. Changing key in a scale or chord mathematically is adding some integer to all of the index values and doing modulo 12. Changing modes within a scale simple involves a position shift of the sequence.

Last week I began exploring the idea of developing some sort of computerized object model to capture these musical theory concepts. As a pianist, knowing theory is extremely important and voicing chords can become quite complex, yet there is sanity in the complexity – a harmony of mathematical precision. Today I introduce “Jazz Toolbox”, the future front-end for which will be located at JazzToolbox.com. Right now I have only developed the back-end object model and calculation engine, which is definitely the foundation of the project. I’ve also written up extensive documentation. Here’s an introduction to the project straight out of my README file:

Jazz Toolbox

Jazz Toolbox is an online Jazz utility driven by a full object-relational and REST model of
concepts in Jazz theory, establishing relationships between chords and scales, and much more.
The web interface is a fully Ajaxified Web 2.0 interface towards exploring these relationships and
answering questions about the jazz science. The REST interface exposes the underlying data model
and relationships to other developers wishing to use Jazz Toolbox as a source for their own web
applications.

Architecture Overview

The core of Jazz Toolbox is a full Ruby object model representing concepts of Jazz theory,
distilled to their most basic concepts and architected in a very abstract manner. The system
is data-centric and all “rules” (for example, the tones in a C7 chord) in theory are
self-contained in the database.

All chord/scale/mode/etc. definitions are stored as a mathematical system (sequences of numbers)
which are then used to perform calculations. For example, putting some chord in a different key
is a matter of adding a semitone delta and doing modulo 12.

While there are currently many chord calculators in existance, to my knowledge this project is the
first one that attempts to fully represent the entirety of Jazz theory as a mathmetical/computational
system exposed through an elegant object model.

Full Documentation

I’ve published the full RDocs which are available here and are very complete.

Examples

Any musician/programmer will appreciate these examples; far more are available in the rdocs:

 Chord['Ebmaj7'].notes
 # => ['Eb', 'G', 'Bb', 'D']
 # Or specify key context with chained methods like this...
 Chord['maj7'].in_key_of('Eb').notes

 Chord['Bmaj7#11'].notes
 # => ['B', 'D#', 'F#', 'A#', 'E#']
 # Note E# - Correct theoretic value for this chord, not F

 Chord['Falt'].notes
 Chord['F7b9#9'].notes
 # => ['F', 'A', 'Eb', 'Gb', 'G#', 'C#']

 Scale['Major'].in_key_of('Eb').modes['Dorian'].notes
 # => ['F', 'G', 'Ab', 'Bb', 'C', 'D', 'Eb']

 Scale['Melodic Minor']['Lydian Dominant'].notes
 # => ['F', 'G', 'A', 'B', 'C', 'D', 'Eb']

 Scale['Major']['Dorian'].chords.symbols
 # => ['min7', 'min6']

 Chord['Amin7'].modes.names
 # => ['A Dorian']

 Scale['Major'][4].chords.symbols
 # => ['maj7#11']

This is definately still a work in progress though it has the potential to become very powerful. I have high ambitions for the front-end web interface for this as well as it could become a valuable tool for Jazz musicians and others trying to nagivate the complex roads of jazz…

21
Feb

Create Structured Data in Migrations

Occassionally I’ll decide to create some structured data in a migration by issuing create statements against my model classes. In a project I’m currently working on, I had to do this several levels deep. Rather than using temporary variables to create the sub items and so-on, all in a lexically flat structure, I came up with this simple one-liner:

def self.with(o); yield o; end

Doing this now allows me to issue those creates with nested data as a series of nested blocks, which is looks much better. For example:

with ChordQuality.create(:name => 'Major', :code => 'MAJ') do |q|
  with q.chords.create(:name => 'Major Triad') do |c|
    c.chord_symbols.create(:name => 'maj')
    c.chord_symbols.create(:name => 'M', :case_sensitive => true)
  end
  with q.chords.create(:name => 'Major 7') do |c|
    c.chord_symbols.create(:name => 'maj7')
    c.chord_symbols.create(:name => 'M7', :case_sensitive => true)
    with c.children.create(:name => 'Major 7 #11') do |cc|
      cc.chord_symbols.create(:name => 'maj7#11')
      cc.chord_symbols.create(:name => 'M7#11')
      cc.chord_symbols.create(:name => 'lyd')
      cc.chord_symbols.create(:name => 'lydian')
    end
  end

  with q.chords.create(:name => 'Major 6') do |c|
    c.chord_symbols.create(:name => 'maj6')
    c.chord_symbols.create(:name => 'M6', :case_sensitive => true)
  end
end

Oh, the beauty of Ruby code blocks!

02
Feb

Wrapping Conditional Access with with_scope

ActiveRecord::Base exposes a great way of keeping access control DRY. A very common paradigm in web application development is showing “all” of something to administrators but only only “active” of something to regular users/visitors. In non-ORM PHP you might do something like like this in each SQL statement:

$sql  = "SELECT * FROM entries WHERE type = 1 ";
$sql .= (!$is_admin ? "AND active = 1" : "");

This isn’t a very well-architected approach since this type of tacking onto the SQL string would have to be done in any statement that involved this table, for all of your “actions” like show, edit, and index. It tightly couples this particularly piece of add-on logic to your base code. In Rails we can scope out this functionality to a “scope_access” method in our controller like so:

class EntriesController < ApplicationController
  around_filter :scope_access

  # (Action Methods)

  protected

  def scope_access
    unless current_user && current_user.is_admin?
      Entry.send(:with_scope, :find => {:conditions => 'active = 1'}) do
        yield
      end
    else
      yield
    end
  end
end

We are declaring an around_filter which uses with_scope if the current user is an admin, otherwise it will do so without scope. This is an excellent example of how Rails allows you to architect your code to be very elegant. Note that with_method is now a protected method on ActiveRecord::Base hence our need to use ClassName.send.

The with_scope method is actually useful for many other purposes including running many but similar find statements. Aside from finders, this can actually scope attributes on create and more. I'd highly recommend you check it out in the Rails documentation and start making extensive use of it.




  • Ben Hughes

    I'm a freelance developer working with Ruby and other modern tools to build web applications, based currently out of Rochester, NY. I love to learn about new technologies and am always trying to achieve elegance and beauty through code.

    When I'm not writing software, I like to play tennis, dabble in jazz piano, and ponder economics. I'm a big fan of: world travel and cultures, jazz music, Korean food, coffee, and having interesting conversations.

  • Recommend Me
July 2010
M T W T F S S
« Jan    
 1234
567891011
12131415161718
19202122232425
262728293031