h = { a:[1,2,3], b:[1,2], c: [1] }
first, *rest = h.map { |k,v| [k].product(v) }
#=> [[[:a, 1], [:a, 2], [:a, 3]], [[:b, 1], [:b, 2]], [[:c, 1]]]
first.product(*rest).map(&:to_h)
#=> [{:a=>1, :b=>1, :c=>1}, {:a=>1, :b=>2, :c=>1}, {:a=>2, :b=>1, :c=>1},
# {:a=>2, :b=>2, :c=>1}, {:a=>3, :b=>1, :c=>1}, {:a=>3, :b=>2, :c=>1}]
Обратите внимание на промежуточный расчет на втором шаге:
first.product(*rest)
#=> [[[:a, 1], [:b, 1], [:c, 1]],
# [[:a, 1], [:b, 2], [:c, 1]],
# [[:a, 2], [:b, 1], [:c, 1]],
# [[:a, 2], [:b, 2], [:c, 1]],
# [[:a, 3], [:b, 1], [:c, 1]],
# [[:a, 3], [:b, 2], [:c, 1]]]