# To multiple records

{% hint style="success" %}
This is the official documentation of the `agent_ruby` Ruby agent.
{% endhint %}

Relationships that point to multiple records are displayed in the frontend in the "Related Data" and "Explorer" Tab.

![Explorer Tab](/files/HrtsYZVOHiIBEzjbuZQd)

### One-to-Many relations

In a one-to-many relationship, one record from a Collection is attached to multiple records of another Collection.

Think about countries and towns: a country has multiple towns, and each town belongs to a country.

```ruby
@create_agent.customize_collection('country') do |collection|
  collection.add_one_to_many_relation(
    'myTown',
    'town',
    {
      origin_key: 'country_id',
      origin_key_target: 'id' # Optional (uses primary key of countries by default)
    }
  )
end
```

### Many-to-Many relations

In a many-to-many relation, 3 Collections are used instead of 2 to build the relation.

This allows multiple records from one Collection to be attached to multiple records from another Collection.

For instance, on a movie recommendation website, each user can rate many movies, and each movie can be rated by many users. The 3 Collections that are used are `users` (the "origin" Collection), `ratings` (the "through" Collection), and `movies` (the "foreign" Collection).

```ruby
@create_agent.customize_collection('user') do |collection|
  collection.add_many_to_many_relation(
    'ratedMovies',
    'movie',
    'rating',
    {
      origin_key: 'user_id',
      foreign_key: 'movie_id',
    }
  )

  # ... and the other one.
  collection.customize_collection('Movie') do |collection|
      # ⚠️ Not 'OneToOne'
    collection.add_many_to_one_relation(
      'whoRatedThisMovie',
      'user',
      'rating',
      {
        origin_key_target: 'id', # Optional (uses primary key of Movie by default)
        origin_key: 'movie_id',
        foreign_key: 'user_id',
        foreign_key_target: 'id', # Optional (uses primary key of User by default)
      }
    )
  end
end
```

### External relations

External relations allow to define Collections which will only be available through the "Related Data" section or a given model.

{% hint style="warning" %}
Note that external relations do not support pagination.
{% endhint %}

```ruby
@create_agent.customize_collection('address') do |collection|
  states = [
    { 'code' => 'AK', 'name' => 'Alaska', 'zip' => [99501, 99950], 'closeTo' => [] },
    { 'code' => 'AL', 'name' => 'Alabama', 'zip' => [35004, 36925], 'closeTo' => ['TE', 'MI', 'GE'] },
    { 'code' => 'AR', 'name' => 'Arkansas', 'zip' => [71601, 72959], 'closeTo' => ['OK', 'TX', 'LO'] },
    { 'code' => 'AZ', 'name' => 'Arizona', 'zip' => [85001, 86556], 'closeTo' => ['NM', 'CO', 'NE'] },
    { 'code' => 'CA', 'name' => 'California', 'zip' => [90001, 96162], 'closeTo' => ['OR', 'NE'] },
  # ....
  ]

  collection.add_external_relation(
    'nearStates',
    {
      # Define schema of the records in the relation.
      schema: { 'code' => 'Number', 'name' => 'String' },

      # Which fields are needed from the parent record to run the handler?
      # Dependencies are optional: by default only the primary key of address would be provided.
      dependencies: %w[country zipCode],

      # Compute list of records from the parent record
      list_records: proc { |record|
        if record['country'] == 'USA'
          state = states.find { |s| s['zip'][0] < record['zipCode'] && record['zipCode'] < s['zip'][1] }
          return states.filter { |s| state['closeTo'].include?(s['code']) }
        end

        return []
      }
    }
  )
end

```


---

# Agent Instructions: 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:

```
GET https://docs.forestadmin.com/developer-guide-agents-ruby/agent-customization/relationships/multiple-records.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
