Lesson 2: Collections & Enumerables (The Logic of Rails)


In React, you spend most of your time mapping over arrays of data to render components. In Rails, you do the exact same thing on the backend.

Mastering Arrays, Hashes, and Symbols is the secret to understanding how Rails handles database records and API responses.


1. Arrays (Just like JS)

Creating an array in Ruby is identical to JavaScript. However, adding elements uses a "shovel" operator (<<), which is very common in Ruby.

JavaScript:

JavaScript
const numbers = [1, 2, 3];
numbers.push(4);

Ruby:

Ruby
numbers = [1, 2, 3]
numbers << 4 # The shovel operator

2. Transforming Data (map, each, select)

In JavaScript, you use forEach, map, and filter. In Ruby, the equivalents are each, map, and select.

each (Like forEach)

Use this when you want to execute code for every item but don't need a new array back.

Ruby
numbers.each do |n|
  puts n
end

map (Transforming)

Use this to create a new array based on the original.

Ruby
doubled = numbers.map { |n| n * 2 }
# Result: [2, 4, 6, 8]

select (Like filter)

Use this to grab specific items that meet a condition.

Ruby
evens = numbers.select { |n| n.even? }
# Result: [2, 4]

3. Hashes & Symbols (Objects & Keys)

In JavaScript, you use Objects {}. In Ruby, we use Hashes. But there is a special type of "key" in Ruby called a Symbol.

What is a Symbol?

A symbol looks like this: :name. Unlike a string ("name"), a symbol is immutable and memory-efficient. Rails uses symbols for almost everything.

JavaScript Object:

JavaScript
const user = { name: "Bilal", age: 26 };
console.log(user.name);

Ruby Hash (Standard Practice):

Ruby
user = { name: "Bilal", age: 26 }
puts user[:name] # Accessing via symbol

4. Iterating Over Nested Data

In a real Rails API, you'll often have an array of hashes (like an array of JSON objects).

Ruby
users = [
  { name: "Ali", age: 30 },
  { name: "Bilal", age: 26 }
]

# Get only the names:
names = users.map { |u| u[:name] }
# Result: ["Ali", "Bilal"]

5. Common Beginner Mistakes

  • Wrong Method: Using each when you meant to use map. Remember: each returns the original array; map returns the new one.

  • The Pipe Syntax: Forgetting the pipes |n| in a block. These are your "arguments" for the iteration, just like (n) => ... in JS.

  • Missing Symbols: Trying to access a hash with user["name"] when the hash was defined with symbols :name.


🧠 Mini Exercise

Test your skills with this dataset:

Ruby
users = [
  { name: "Ali", age: 30 },
  { name: "Bilal", age: 26 },
  { name: "Sara", age: 22 }
]

Try to write the code for these 4 steps:

  1. Print every user's name to the console.

  2. Create an array called ages containing only the ages.

  3. Filter the list to find users older than 25.

  4. (Advanced) Return only the names of users older than 25.

Solution:

Ruby
# 1
users.each { |u| puts u[:name] }

# 2
ages = users.map { |u| u[:age] }

# 3
seniors = users.select { |u| u[:age] > 25 }

# 4
senior_names = users.select { |u| u[:age] > 25 }.map { |u| u[:name] }

What’s Next?

Now that you can handle data, we need to talk about Object-Oriented Programming (OOP). In Lesson 3, we’ll learn about Classes and Objects—the DNA of every Rails Model.


Ready to move on? Reply with "START LESSON 3"!

 

Comments