Page 1 of 36, Now with Less NSA?

As part of my site overhaul, I have been wanting to make the whole site run on SSL. Now that Let’s Encrypt is here, it’s easy and free to add SSL to a website. I wanted a lightweight tool for installing and maintaining the certificates, and was really easy to setup and use. I even managed to score an A grade on the SSL Labs Report.

Now, if only the other sites I used would SSL everything. Cough, Amazon, cough.

Once I clean up my Ansible scripts, I’ll publish them.

I'm Back!

After neglecting my website for years, it was time to smash it and reassemble the pieces.

My goals:

  • (Mostly) static site - I work on enough web infrastructure for my day job that I don’t really want to maintain more in my free time. So I’m dropping nearly everything that was dynamic. I can get a lot of the features from the old dynamic site, like blog pagination and such, from a static site preprocessor like Middleman. It plays nicely with my Ruby on Rails background.

  • Modern - I want to be able to use my site on my iPhone and iPad.

  • Automation - I do enjoy the convenience of deploying sites with one command and then everything Just Works™. I’ve become a fan of Ansible recently. I have a small amount of Ansible code that I use to configure, update, and deploy the site.

  • Deprecation - There are parts to my site that are simply ancient. I’m going to start phasing them out. I hate to send 404s to people, but I only have so much time and it’s not worth maintaining anymore. I’m adding deprecation notices to those pages, not linking them from my home page, and will remove them eventually.

I haven’t figured everything out yet. I still want a solid way to handle lots of pictures efficiently, with consideration for screen sizes, densities, and bandwidth. In the meantime I’ll keep my old homegrown code around for a while.

Hopefully this setup will be a good foundation for the next several years.

Until next time!

Ruby's shallow copies of hashes

When you try to copy a Ruby hash using .dup or .clone, you get what is called a “shallow” copy. The data in the hash below the first level just seems to be referenced, so if you have a hash within the hash, and try to change a value in the deeper hash, the value is changed even for the original hash you ran the .dup on. To get a full (“deep”) copy of a hash, you have to run an inelegant hack using Marshal to copy it: copy_hash = (Marshal.load(Marshal.dump(source_hash))). This apparently applies to arrays too. See the code below for an example, and I hope this saves you hours of debugging.

# Ruby unexpected behavior when using .clone or .dup on a hash (or array)

# create a hash and freeze it so it shouldn't be modified
MY_HASH = { :one => { :first => 'eins', :second => 'zwei' } }.freeze

puts MY_HASH.inspect # {:one=>{:first=>"eins", :second=>"zwei"}}

new_hash = MY_HASH.dup # copy the hash, unfrozen

new_hash[:one][:second] = 'dos'

puts new_hash.inspect # {:one=>{:first=>"eins", :second=>"dos"}}

# original hash should not be modified, but it is!
puts MY_HASH.inspect # {:one=>{:first=>"eins", :second=>"dos"}}

# this happens apparently because hash copies are "shallow" and only
# contain pointers to values
# a "deep" copy requires ugliness using Marshal

MY_HASH2 = { :one => { :first => 'eins', :second => 'zwei' } }.freeze

puts MY_HASH2.inspect # {:one=>{:first=>"eins", :second=>"zwei"}}

new_hash2 = Marshal.load(Marshal.dump(MY_HASH2))

new_hash2[:one][:second] = 'dos'

puts new_hash2.inspect # {:one=>{:first=>"eins", :second=>"dos"}}

# now the original hash is intact:
puts MY_HASH2.inspect # {:one=>{:first=>"eins", :second=>"zwei"}}

Rails validations with accepts_nested_attributes_for and _destroy

I was recently working on a Rails app that has a form with a parent item and child items on the same form. Ryan Bates’ complex form examples is a good place to start with this. That code will give you a simple form setup with some Javascript for adding and removing rows of children.

It works pretty well, except that in my case, I needed to ensure that each parent had a minimum of one child. I had a validation which checked for this, but it only worked for creating new records. If I removed all the child rows during an edit, the form would still save successfully. It turns out that the key is in the Rails documentation: “Note that the model will not be destroyed until the parent is saved.” So my validation was still happily finding a child row, even though it was set to be deleted. It took me some time before I found the right way to check for this, but the marked_for_destruction? method seems to do the trick. Here’s my code:

class Project < ActiveRecord::Base
  has_many :tasks
  accepts_nested_attributes_for :tasks, :reject_if => :all_blank,
    :allow_destroy => true

  def validate
    # require a minimum of one task
    undestroyed_task_count = 0

    tasks.each { |t| undestroyed_task_count += 1 unless t.marked_for_destruction? }

    if undestroyed_task_count < 1
      errors.add_to_base 'There must be at least one task'

Hope this helps someone!

My first attempt at a mobile web app

German-English Dictionary Web App
Is this thing on? So it’s been a forever since I’ve blogged, but we’ll see if I still can. Happy Thanksgiving at least! Anyway, I’ve been wanting to build stuff for my iPhone. While I’ve been experimenting with Objective C for a native app, I wanted to actually build and publish something. So I have abandoned my Objective C code snippets for now and decided to go with things I know and build a Ruby on Rails site. There are various libraries to let you style a site for mobile browsers. I went with jQTouch, which is covered pretty well by these Railscasts and Peepcode screencasts. I like using the German-English dictionary site Beolingus, but I wanted to use it more easily on my iPhone. It turns out the data is downloadable, so I decided to build a web application with mobile front-end. Here it is:

Denglisch (that’s a term for English and German mixed together) I really wanted to build the site in Rails 3, but most of my stuff is hosted on Dreamhost, and I’ve read about various problem getting those apps running right now. So it’s done in Rails 2.3.10 instead. The Rails side is pretty simple, just one model for the data, a rake script to import the textfile into the database, one controller and two actions. Then there’s a little bit of jQuery Javascript code to handle the Ajax form submission.

Home Screen Icon
I knew how to do a lot of these bits, but I learned things along the way too. For one, I didn’t know that the iPhone could make a native-looking app out of a website. The website can include icons and a splash screen, and when you add the bookmark to your home screen, the icon will show up there. The splash screen shows up when the website is loading, and then the web app uses the full screen without the Safari toolbars. Cool. I found jQTouch to be fairly easy to use, but the download from their home page is a good bit older than the code they have on Github. I ran into an issue with the latest version that I had to look for a solution from the bug list. They don’t have much documentation either. The Peepcode screencast was very helpful, but it isn’t free, and jQTouch has changed a bit since it was published (e.g. the new “jqt” div).

Anyway, I’ve tested this on my iPhone…I’m curious to hear if it works for the iPad and other mobile devices. It was a good hobby project anyway. Have fun!

Update 2016-01-17: I eventually rewrote this code with Sinatra instead of Rails. I stopped hosting either version, but here’s the Sinatra-based source code.

Next page