> For the complete documentation index, see [llms.txt](https://crystal-garage.gitbook.io/lustra-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://crystal-garage.gitbook.io/lustra-docs/querying/the-collection-object/fetching-the-query/each-map-fetch.md).

# Each and Fetch

`Collection` includes `Enumerable(T)`, so calling enumeration methods resolves the query.

## `each`

`each` builds model instances:

```crystal
Post.query.where(user_id: 1).each do |post|
  puts post.title
end
```

Pass `fetch_columns: true` when you also need custom selected fields in `attributes`:

```crystal
Post.query
  .select("posts.*", "COUNT(post_tags.id) AS tags_count")
  .left_join(:post_tags) { post_tags.post_id == posts.id }
  .group_by("posts.id")
  .each(fetch_columns: true) do |post|
    puts post.attributes["tags_count"]
  end
```

## `map`

`map` also builds model instances, then applies the block:

```crystal
emails = User.query.where(active: true).map(&.email)
```

Like `each`, it accepts `fetch_columns`:

```crystal
labels = User.query
  .select("users.*", "LOWER(email) AS normalized_email")
  .map(fetch_columns: true) { |user| user["normalized_email"].as(String) }
```

## `pluck_col` and `pluck`

Use `pluck_col` when you only need one column and do not need model instances:

```crystal
names = User.query
  .where(active: true)
  .order_by(id: :asc)
  .pluck_col("email")
```

Without a type argument, `pluck_col` returns `Array(Lustra::SQL::Any)`. Pass a type when you want a typed array:

```crystal
emails = User.query.pluck_col("email", String)
ids = User.query.pluck_col(:id, Int64)
```

Use `pluck` for multiple columns:

```crystal
posts = Post.query.pluck("title", "published")

posts.each do |(title, published)|
  puts "#{title}: #{published}"
end
```

Named `pluck` returns typed tuples:

```crystal
users = User.query.pluck(
  "email": String,
  "LOWER(email)": String
)
```

`pluck` and `pluck_col` execute a copied query with a new `SELECT` list, so they do not instantiate models. Use them for simple column extraction. Use `each`, `map`, or `fetch` when you need models or full raw rows.

String fields are SQL fragments. Use symbols for simple column names when possible, and do not interpolate untrusted input into string fragments.

## `to_a`

`to_a` loads all matching model records into an array:

```crystal
users = User.query.where(active: true).to_a
```

Use this when you intentionally want array behavior:

```crystal
users = User.query.order_by(id: "ASC").to_a
user = users[10]?
```

`to_a(fetch_columns: true)` keeps custom selected fields in each model's `attributes` hash.

## `fetch`

`fetch` comes from the lower-level SQL query builder. It yields `Hash(String, Lustra::SQL::Any)` rows instead of model instances:

```crystal
Post.query.where(user_id: 1).fetch do |row|
  puts "#{row["id"]} - #{row["title"]}"
end
```

Use `fetch` when you need raw SQL rows or want to avoid model construction overhead.

`fetch(fetch_all: true)` loads the result rows before yielding them. This is useful when the block itself needs to run more SQL, because the original result set is closed before the block runs.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://crystal-garage.gitbook.io/lustra-docs/querying/the-collection-object/fetching-the-query/each-map-fetch.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
