InquiryLabs

Politics, Programming and Possibilities

Archive for the ‘Software Engineering’ Category

Any Designers Looking for a Small Job?

When Dave and I first developed FamilyAnywhere.com, we built it with the intent that some day we would hire a Real Designer to make it look like a professional site. For anyone who cares to make a visit right now, it definitely still looks like a couple of coders put it together—and that would be an accurate observation.

So my question to put to out there today is, are you a website designer or graphics guru looking for a side job? We’d love to talk to you. Drop me (Duane) a line at duane.johnson@gmail.com.

TextMate Footnotes v.1.6 Released

Update: The repository has moved slightly, since the Rails.tmbundle got renamed to “Ruby on Rails.tmbundle”. The URL looks like this (no newlines):

http://macromates.com/
  svn/Bundles/trunk/Bundles/Ruby on Rails.tmbundle/
  Support/plugins/footnotes

This release of the TextMate Footnotes plugin has several new and helpful features:

  • Improved the Session and Params debug information
  • Added a Cookies debug box
  • Added a General debug box where you can send your long Javascript messages that don’t belong in an ‘alert’ box.
  • Non-TextMate users can now take advantage of all of the above features, since they are not TextMate-specific.
  • Added a “View Layout Code” link for TextMate users that takes them directly to the layouts/whatever.rhtml file.
  • Improved the way Footnotes detects whether or not it should show up on a page. For example, it is now more accurate at detecting when the current rendered view is an rxml or rjs file (therefore, no footnotes should show up).
  • The Footnotes code is now inserted in to the HTML “head” and “body” sections of the output, as they should be. HTML code will no longer trail after the closing “html” tag.

I’ve also moved the project in to the TextMate Repository, so you can either get it with TextMate, or use subversion to get it directly here:

svn --username anon --password anon co http://macromates.com/
  svn/Bundles/trunk/Bundles/Rails.tmbundle/
  Support/plugins/footnotes footnotes

(Note: the subversion checkout command above should all be on one line.)

ActiveRecord gives a lot of flexibility with its 16 callbacks. I’ve never needed anything more granular than that flexibilty until today.

In trying to automate the process of saving files on Amazon S3, I needed a callback that would be triggered after the creation of my “Photo” record, but before the creation of several associated objects. (These ActiveRecord objects were being held in memory via the association “build” method, and thus had not yet been inserted in to the database.)

Delving deep in to ActiveRecord to figure out how those build-associated objects were being automatically inserted in to the database when calling “save” on my Photo object, I found out it’s a lot easier than it might seem.

Just define your “after_create” callback before the call to “has_many” in your class. For example:


class Photo < ActiveRecord::Base
  # This callback must be defined before "has_many :versions" so
  # that it gets called *after* the Photo is created, but *before*
  # the versions are inserted in to the DB.
  after_create :send_id_to_versions

  has_many :versions

  def send_id_to_versions
    ...
  end
end

If you switch the order of the after_create and the has_many above, the “Version” objects will be inserted to your database before the call to “send_id_to_versions”.

Hope that saved you an hour or two! ;)

Ruby Hashes of Arbitrary Depth

UPDATE: In the comments, Kent has provided a complete solution to this problem:

hash = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)}))


I would love to see this integrated in to the Hash class at some point, but if not, we can (with Ruby’s kind acceptance) do it ourselves:

class Hash
  def self.arbitrary_depth
    Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)}))
  end
end


Thus,

hash = Hash.arbitrary_depth


While working on FamilyLearn.com today, I ran in to an interesting Ruby puzzle–how do you create a PHP-like Hash object that accepts keys to an arbitrary depth?For example, the following will not work in Ruby:
h = Hash.new
h[:one][:two] = "uh-oh!"
# NoMethodError: undefined method `[]=' for nil:NilClass

The solution? Pass in a proc that will tell Hash to create a second hash by default for each key that is not found:

h = Hash.new { |h,v| h[v]= Hash.new }
h[:one][:two] = "uh-oh!"
# => "uh-oh!"
h
# => {:one=>{:two=>"uh-oh!"}}

Much better. But that’s only two-deep. What about n-deep? The solution I found isn’t fully “arbitrary” on demand, but it should work for most cases:

class ArbitraryDepthHash
  def self.arbitrary_depth_proc(depth = 1)
    proc { |h,v| h[v] = Hash.new(&arbitrary_depth_proc(depth-1)) }
  end

  def self.[](depth)
    Hash.new(&arbitrary_depth_proc(depth))
  end
end

h = ArbitraryDepthHash[5]
h[:one][:two][:three][:four][:five] = "wow!"
# => "wow!"
h
# => {:one=>{:two=>{:three=>{:four=>{:five=>"wow!"}}}}}

Updated ColumnComments Plugin (v.1.2)

Gerardo Lisboa recently enquired about the ColumnComments plugin, noting that comments can not be added to columns during the creating of a table (usually the most useful time to add comments!) He is, of course, absolutely right–the comments option did not work in version 1.1. In response, I wrapped up a zip file of my current implementation and sent him the update.

For anyone else who is using ColumnComments, I recommend using this upgrade (MySQL only).

Download the zip file here, and then unzip it in to your Rails app’s vendor/plugins directory.

How to Use cURL to Test RESTful Rails

I’ve begun experimenting with the new Edge Rails code that includes built-in support for REST. (The code that was once in the simply_restful plugin is now a part of Edge Rails.) With the capability to generate multiple types of output per action, it has become more and more useful to test actions on the command-line using cURL. Here are some useful cURL parameters I’ve used:

  • -X [action]: Allows you to specify an HTTP action such as GET, POST, PUT or DELETE.
    Example:

    curl -X DELETE http://localhost:3000/books/1
  • -d [parameter]: Lets you set variables as if they were POSTed in a form to the URL. Note that this automatically makes the request a POST HTTP action type (no -X necessary).
    Example:

    curl -d "book[title]=Test" -d "book[copyright]=1998"
    http://localhost:3000/books
  • -H [header]: Gives you the option of setting an HTTP header such as Content-Type or Accept. This is particularly useful for requesting text/xml as the Accept type.
    Example:

    curl -H "Accept: text/xml"
    http://localhost:3000/books/sections/1

Putting it all together, here’s a cURL command that updates the title of a Book object using the PUT action and expects an xml response:

curl -H "Accept: text/xml" -X PUT -d "book[title]=Testing Again"
http://localhost:3000/books/1

Rails Plugins Directory at AgileWebDevelopment

Benjamin Curtis has been seeding his Rails Plugins Directory project by taking announcements on the Rails list and documenting them on his website. He added tags a while back, and the list of plugins is now very impressive!

Take a look yourself and see if you like it.

Two Months Later

It’s been almost two months since my last post, and that makes it about time I wrote again. I’ve been silent on this blog primarily for three reasons:

  1. My recent work has required that I develop in PHP. As of this week, I’m back on the Ruby on Rails track.
  2. My brother passed away in June, leaving this world unexpectedly. It’s been a difficult time for me and my family.
  3. My world view has changed significantly as a result of my findings in May, and it has taken some time to process the implications.

I will post about each of these items separately.

DevBoi — Documentation in Your Browser

This seems to have been around for a while, but I missed the announcement some months ago. It’s a cool little in-browser documentation package that provides docs in . It also has some CSS, PHP and HTML documentation packages that you can download.

It’s called DevBoi (where’d that name come from?) and it’s available from Martin Cohen.

Press Release at inquiry.newsvine.com

I just created a “blog” at inquiry.newsvine.com where we put our FamilyAnywhere.com press release / announcement. Check it out if you’re interested in how Family Anywhere got started.subsidized stafford loan 2008-2009apyday 2000 loanloan bank rajhi malaysia al personalloan amerization oftexas in 500 fiko loans carequlity 530 home fico loansloans insurers maplight ab orgfico score 500 for commercialloans financing Map