Politics, Programming and Possibilities
8 Oct
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.
20 Sep
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
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!”}}}}}
1 Sep
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.
4 Aug
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:
curl -X DELETE http://localhost:3000/books/1
curl -d "book[title]=Test” -d “book[copyright]=1998″ http://localhost:3000/books
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
31 Jul
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.
12 May
I had a doozy of a bug today: an “Album” model has_many “Track” objects, but calling album.tracks.clear was not deleting or destroying the associated tracks in spite of my having explicitly set :dependent => :destroy on the has_many association.
As it turns out, my object (the album) was being stored in the session, and therefore the associated tracks were also in the session. When I called album.tracks.clear, the foreign keys were nullified instead of the rows destroyed.
The solution: store album ids in the session instead of the whole object, and do an Album.find(session[:album_id]).
25 Apr
Here’s a method that will allow you to call to_xml on an ActiveRecord::Errors object. We’re using this to pass errors between web apps via a web service api.
class ActiveRecord::Errors
def to_xml(options = {})
options[:indent] ||= 2
options.reverse_merge!({ :builder =>
Builder::XmlMarkup.new(:indent =>
options[:indent]), :root => “errors” })
options[:builder].instruct! unless options.delete(:skip_instruct)
options[:builder].__send__(options[:root].to_s.dasherize) do |xml|
@errors.each do |key, value|
xml.__send__(key.to_s.dasherize) do |xm|
for message in value
xm.message(message)
end
end
end
end
end
end
25 Apr
So here’s an idea I’ve been tossing around on the Textmate IRC channel and mailing list: What if Textmate supported multiple arbitrary simultaneous carets (MASC)? Allan Odgaard didn’t like the idea on first inspection, because it involves using the mouse–something that he is philosophically opposed to (for obvious reasons–it’s a text editor, after all). But I think there’d be many people who would receive this feature with eager arms and an appropriate amount of salivation.
So what is the idea? Here’s my original mailing list post:
What if you could add multiple carets to the current document by command-clicking? I imagine this to work in a way almost identical to that of the current snippet mechanism. For example: choose three caret locations, start typing, and in each location your text will show up. Press tab and the caret will focus in on the second of the two locations, highlighting the newly typed text (if any). Tab again and it moves to the third.
It would also be ideal to be able to highlight multiple selections in the same way–kind of like a powerful replace mechanism. Command-click and select three words in the document, then type one new word, and incrementally, all three words change to the new one.
Here is a screencast of MASC in action (Quicktime, 27 MB):
Update: The bundle is available as a disk image here. Key bindings and the “ß” marker character are subject to change. Use alt-s to mark and alt-f to convert markers to a snippet.
Update #2: No longer uses the beta marker. Uses special angle brackets instead.
Update #3: There is now a page for My Textmate Bundle that has updated information and a new (shorter) screencast.
26 Feb
My friends on IRC have helped me track down and understand better the way TextMate helps its bundles by setting up the environment for Ruby code. The Rails bundle now uses the TM_RUBY environment variable to determine which ruby on your system to use (i.e. if you have multiple ruby shell commands installed).
One of the biggest problems with this environment stuff has been trying to figure out the best way to support all of the many ways you can get Ruby on your system: the built-in version patched with fixrbconfig, DarwinPorts, your own version, or perhaps even Locomotive’s ruby-in-a-box. For those of you who’ve been experiencing problems with past versions of the Rails bundle, I think this one may fix it for you. If you’re still having problems, try adding a TM_RUBY environment variable to your TextMate shell variables (in Preferences, go to Advanced, then Shell Variables). Point TM_RUBY to the location you installed ruby at.
As usual, please feel free to contact me and we can try to work out a solution if you’re still having trouble. Comments showing your problems or solutions are also welcome.
18 Feb
Due to some great comments already, I decided to fix up what I can for the night and wrap this up. Version 0.6 will ask you before overwriting an already-existing partial, and the Intelligent Go To File command is a little bit more robust.
There’s also a subversion repository of this TextMate bundle at:
svn://syncid.textdriven.com/svn/opensource/syncpeople_on_rails/trunk
You can download version 0.6 here.
The original announcement of version 0.5 can be found here.