How to get “x[y][z]” out of a hash ?

This made life with our form helpers a lot easier, since they take normal or nested keys <-> name of the input and prefilled value through params.

Any alternative is appreciated, since its pretty complex/hacky, the name is weird too …
(a simple to_query.split(‘=’)).inject… can work too, but would stringify all values and keys)

Usage

{'x'=>{'y'=>{'z'=>1}}}.value_from_nested_key('x[y][z]') == 1

Code

class Hash
  # {'x'=>{'y'=>{'z'=>1}}.value_from_nested_key('x[y][z]') => 1
  def value_from_nested_key(key)
    if key.to_s.include?('[')
      match, first, nesting = key.to_s.match(/(.+?)\[(.*)\]/).to_a
      value = self[first]
      nesting.split('][').each do |part|
        return nil unless value.is_a?(Hash)
        value = value[part]
      end
      value
    else
      self[key]
    end
  end
end

Took me a while to find out, so ill share :)

# 1.8.7 / 1.8.6 only, not 1.9.x
'a'[0] == 97

# universal 1.8.x / 1.9.x
97.chr == 'a'
97 == ?a

# by mr woeber
'a'.unpack('C*').first == 97
[97].pack('C*') == 'a'

Instead of flipping values around by hand and possibly making mistakes, simply put an ‘un’ before them

Usage

class RenameStuff < ActiveRecord::Migration
  def self.up
    rename_column :users, :username, :login
    rename_column :users, :e_mail, :email
  end

  def self.down
    # simply cody and add 'un'
    unrename_column :users, :username, :login
    unrename_column :users, :e_mail, :email
  end
end

Code

# convenience method, so that rename statements do not need to be reversed by hand
class ActiveRecord::ConnectionAdapters::Table
  def unrename(a,b)
    rename b,a
  end
end
module ActiveRecord::ConnectionAdapters::SchemaStatements
  def unrename_column(table_name, a, b)
    rename_column(table_name, b, a)
  end
end

Generates a checksum for a given folder without considering updated_at/created_at/permissions, just the content.

def self.checksum(dir)
  files = Dir["#{dir}/**/*"].reject{|f| File.directory?(f)}
  content = files.map{|f| File.read(f)}.join
  require 'md5'
  MD5.md5(content).to_s
end

Simpler but with modification/user-rights etc:

Unix

tar cf - /dir | md5sum

Mac

tar cf - /dir | md5

A simple hack to get no more memcache timeouts in production.
You should add some kind of error notification above the ‘nil’ line, to know that memcache is no longer behaving properly.
(If it does not work, check if MemCache.new.cache_get_with_timeout_protection is defined -> load the hack in after_initialize)

code

class MemCache
  def cache_get_with_timeout_protection(*args)
    begin
      cache_get_without_timeout_protection(*args)
    rescue MemCache::MemCacheError => e
      if e.to_s == 'IO timeout' and (Rails.env.production? or Rails.env.staging?)
        nil
      else
        raise e
      end
    end
  end
  alias_method_chain :cache_get, :timeout_protection
end

try it

start script/console
kill -s STOP memcache-pid
try reading from cache in console
kill -s CONT memcache-pid