DEV Community

Germán Alberto Gimenez Silva
Germán Alberto Gimenez Silva

Posted on • Originally published at rubystacknews.com on

đź§  Hash Transformations in Ruby: index_by vs index_with

đź§  Hash Transformations in Ruby: index_by vs index_with
Hash Transformations in Ruby: index_by vs index_with

July 4, 2025

Ruby and Rails developers often appreciate how expressive and elegant the language is—especially when it comes to working with collections.

One of the lesser-known gems in Ruby’s Enumerable toolbox is the pair of methods: index_by and index_with. Both are incredibly powerful for transforming arrays into hashes in a clean, readable, and performant way—without manual loops or verbose logic.

Let’s break them down with real-world examples 👇


🔑 index_by: Turn a collection into a hash keyed by a custom value

The index_by method is perfect when you have an array of objects and want to convert it into a hash, using a specific attribute or computed value as the key.


users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" }
]

users.index_by { |u| u[:id] }
# => { 1 => { id: 1, name: "Alice" }, 2 => { id: 2, name: "Bob" } }

Enter fullscreen mode Exit fullscreen mode

âś… Use case: Quickly creating lookup tables by ID, email, or any unique identifier.

Another handy use:


files = ["/tmp/test.txt", "/var/log/app.log"]
files.index_by { |path| File.basename(path) }
# => { "test.txt" => "/tmp/test.txt", "app.log" => "/var/log/app.log" }

Enter fullscreen mode Exit fullscreen mode

âš™ index_with: Build a hash from existing keys

While index_by starts from values , index_with starts from keys and assigns values using a block.


names = ["Alice", "Bob"]
names.index_with { |name| name.length }
# => { "Alice" => 5, "Bob" => 3 }

Enter fullscreen mode Exit fullscreen mode

Another concise example:


%w[red green blue].index_with(&:upcase)
# => { "red" => "RED", "green" => "GREEN", "blue" => "BLUE" }

Enter fullscreen mode Exit fullscreen mode

And one that’s especially practical in real life:


sentence = "the quick brown fox jumps over the lazy dog"
words = sentence.split
words.uniq.index_with { |w| words.count(w) }
# => { "the"=>2, "quick"=>1, "brown"=>1, ... }

Enter fullscreen mode Exit fullscreen mode

đź§µ ActiveRecord Pro Tip

index_by is especially useful with ActiveRecord:


User.all.index_by(&:email)
# => { "alice@example.com" => #<User id: 1>, "bob@example.com" => #<User id: 2> }

Enter fullscreen mode Exit fullscreen mode

This helps avoid N+1 queries and gives you a simple way to organize records for quick lookup.


âś… When to Use What?

Article content

Both methods support writing expressive, readable, and functional-style Ruby. Once you start using them, you’ll likely find many opportunities to replace verbose logic with these elegant tools.

Article content


💬 Have you used index_by or index_with in your projects? Do you have a favorite use case or a cool tip? Drop it in the comments—I’d love to see how others apply these patterns.

RubyOnRails #RubyTips #Developers #CodeBetter #RailsPatterns

Top comments (0)