A minimal just-in-time Ruby MySQL Object Map
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Norm — The Norm Object Relational Mapper

  • Norm defines the database schema as it is used.
  • Norm is semi-kinda-sorta inspired by jQuery:
    • There are methods like $() (Norm[] and Norm::Model[]) that will return either one or several items depending on the input.
    • Chainability is a design goal that has not been realized except for column addition and removal. I’d like Norm::Model[] results to be chainable, like jQuery’s $().
    • I’m interested in applying the jQuery pattern of methods being a setter if an optional argument exits and a getter if it doesn’t. This allows chaining setters and getters, which can be nice.
  • Norm is vaguely inspired by Datamapper. They seem like a really cool project.
  • Norm takes “convention over configuration” seriously.
  • Norm is < 300 lines. Norm came about because I was playing with Sinatra and wanted an ORM that was similarly minimalist and lightweight (although Norm is not at all fast, unlike Sinatra).
  • Caveats
    • Norm is a bad idea. That’s okay. It’s just for practice.
    • Norm makes RDBMS purists cry. Crying isn’t ACID compliant.
    • Norm is Not an ORM, really, in that it’ll never be a full-fledged ORM.
    • Norm only depends on the mysql gem. Requiring activesupport would make some things easier, but is not within the scope of this experiment.
    • Norm is MySQL-only and probably will always be that way.
    • Norm is not intended to be used for anything serious. Norm is an experiment and a self-educational lesson.
    • Norm makes more database calls than necessary. A lot more.
require 'norm'
Norm.database = "norm"
desk = Norm::Desk.new :height => '3 feet', :depth => '2 feet', :width => '2 feet'

will connect to database “norm,” create a table “desk,” and add three columns to it, as well as making and saving the first record, which can now be accessed like Norm::Desk.first, Norm::Desk[desk.id], Norm::Desk['where height = "3 feet"'], or (at this point), Norm::Desk.all


You can make a new Norm class (and table) as simply as

require 'norm'
class Desk
  include Norm

or, for a bit of lazy:

require 'norm'

either of which will make a table `desk` on definition.

  • d = Desk.new both makes and saves a new desk, auto-incrementing an id column (d.id).
  • d.purpose = 'writing' adds a column desk.purpose in mysql and sets it for the row with id d.id.
  • d.delete deletes that desk.


Norm operates on the convention that associations are named the same thing as the associated table name. The association is singular whether or not it’s a plural association. You’re a programmer, you can live without pluralization.

require 'norm'
p = Norm::Parent.new
c1 = Norm::Child.new
c2 = Norm::Child.new

c1.parent = p
c2.parent = p

p.child.size #=> 2

That’s all for now. Hope you think it’s interesting!