You could use [`Enumerable#count`](http://ruby-doc.org/core-2.4.0/Enumerable.html#method-i-count):

    string.chars.count { |char| vowels.has_key?(char) }

You very rarely need to declare a variable (`i` in this case), and then modify it form inside a block; there's almost always a better way in Ruby.

So while calling `count` and passing a block is the most direct, you could also have done something like:

    string.chars.select { |char| vowels.has_key?(char) }.count

Same idea, just written out in separate filter/count steps.

You can also skip the `return` since that's implied at the end of a method.

I'd also use a plain array for the vowels. Looking up hash keys is faster, sure, but does it _really_ matter that much? Nah. "Premature optimization is the root of all evil" and all that.

    vowels = %w(a e i o u) # same as ["a", "e", "i", ...]

and then the block becomes:

    vowels.include?(char)

If you keep the vowels array sorted, you can use `bsearch` if you want to speed it up a little. Or you can construct the hash in code, instead of typing all that `=> 0`:

    list = %w(a e i o u)
    vowels = Hash[list.zip(list)] # => { "a" => "a", "e" => "e", ... }

----

Of course you could also do something funky like this: Remove all the vowels and see how much shorter the string is afterward:

    def count_vowels(string)
      string.length - string.gsub(/[aeiou]/, '').length
    end

This is also easily made case-insensitive:

    string.length - string.gsub(/[aeiou]/i, '').length

Or instead of `gsub` you can use `tr`:

    string.length - string.tr('aeiou', '').length

(or `'aeiouAEIOU'` for case-insensitivity.)

---

Alternatively, you could extend/monkey-patch the `String` class a little. I wouldn't recommend it for production code, though. This is just illustrate some Ruby features:

    class String
      def vowel?
        self =~ /\A[aeiou]\z/ ? true : false
      end
    end
    
    def count_vowels(string)
      string.chars.count(&:vowel?)
    end

The `&x` syntax is a shorthand meaning "invoke `x` on each element in the collection", so it's equivalent to `{ |e| e.x }`.

Again, this is mostly for fun. I just thought it made the `count_vowels` method nice and short. And of course, `count_vowels` could itself be monkey-patched onto `String`, so you could just call `some_string.count_vowels`. But again, monkey-patching - while fun - shouldn't be the first thing you reach for. Just illustrating the principle.