vars = {foo: [1, 2, 3], bar: [4, 5, 6, 7]}
(v = vars.map {|k, v| ([k] * v.length).zip(v) }).first.product(*v.drop(1)).
map {|args| args.reduce({}) {|h, (k, v)| h.tap {|h| h[k] = v }}}
# => [{:foo=>1, :bar=>4},
# => {:foo=>1, :bar=>5},
# => {:foo=>1, :bar=>6},
# => {:foo=>1, :bar=>7},
# => {:foo=>2, :bar=>4},
# => {:foo=>2, :bar=>5},
# => {:foo=>2, :bar=>6},
# => {:foo=>2, :bar=>7},
# => {:foo=>3, :bar=>4},
# => {:foo=>3, :bar=>5},
# => {:foo=>3, :bar=>6},
# => {:foo=>3, :bar=>7}]
Это работает с произвольным множеством записей и произвольных ключей.