# Search on a smart field with two joints

This example shows you how to search on a smart field which display a belongsTo smart relationship.\
\
We have an **order** which `belongsTo` a **customer** which `hasOne` **address**. \
\
We’ve created a Smart Relationship `(delivery address)`on the **order** table that acts like a shortcut between the **order** and the **address**.

![](/files/-M3l2ndHjhqSjPaTpAEc)

## Requirements

* An admin backend running on forest-express-sequelize

## How it works

### Directory: /models

This directory contains the `orders.js` , `customers.js` and `addresses.js` files where the models are declared.

{% tabs %}
{% tab title="orders.js" %}

```javascript
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  const Orders = sequelize.define('orders', {
    //...
  }, {
    tableName: 'orders',
    underscored: true,
    schema: process.env.DATABASE_SCHEMA,
  });

  Orders.associate = (models) => {
    Orders.belongsTo(models.customers, {
      foreignKey: {
        name: 'customerId',
        field: 'customer_id',
      },
      as: 'customer',
    });
  };

  return Orders;
};
```

{% endtab %}

{% tab title="customers.js" %}

```javascript
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  const Customers = sequelize.define('customers', {
    ...
  }, {
    tableName: 'customers',
    underscored: true,
    schema: process.env.DATABASE_SCHEMA,
  });

  Customers.associate = (models) => {
    Customers.hasMany(models.orders, {
      foreignKey: {
        name: 'customerId',
        field: 'customer_id',
      },
      as: 'orders',
    });
    Customers.hasOne(models.addresses, {
      foreignKey: {
        name: 'customerId',
        field: 'customer_id',
      },
      as: 'addresses',
    });
  };

  return Customers;
};
```

{% endtab %}

{% tab title="addresses.js" %}

```javascript
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  const Addresses = sequelize.define('addresses', {
    addressLine1: {
      type: DataTypes.STRING,
      field: 'address_line_1',
    },
    ...
  }, {
    tableName: 'addresses',
    underscored: true,
    schema: process.env.DATABASE_SCHEMA,
  });

  Addresses.associate = (models) => {
    Addresses.belongsTo(models.customers, {
      foreignKey: {
        name: 'customerId',
        field: 'customer_id',
      },
      as: 'customer',
    });
  };

  return Addresses;
};
```

{% endtab %}
{% endtabs %}

### Directory: /forest

This directory contains the `orders.js` file where the BelongsTo Smart Relationship `delivery_address`is declared.\
\
A belongsTo Smart Relationship is created like a Smart Field with the `reference` option to indicates on which collection the Smart Relationship points to.\
\
As for Smart Field, the search is not supported by default. So we'll have to implement the logic using [Sequelize querying methods](https://sequelize.org/master/manual/model-querying-basics.html).

{% code title="/forest/orders.js" %}

```javascript
const models = require('../models');
const { Op } = models.Sequelize;

collection('orders', {
  fields: [{
    field: 'delivery_address',
    type: 'String',
    reference: 'addresses.id',
    // display the belongsTo Smart Relationship
    get: function (order) {
      return models.addresses
        .findAll({
          include: [{
            model: models.customers,
            as: 'customer',
            where: { id: order.customerId },
            include: [{
              model: models.orders,
              as: 'orders',
              where: { ref: order.ref }
            }]
          }],
        })
        .then((addresses) => {
          if (addresses) { return addresses[0]; }
        });
    },
    // search on the belongsTo Smart Relationship
    search(query, search) {
      query.include.push({
        model: models.customers,
        as: 'customer',
        include: [{
          model: models.addresses,
          as: 'addresses',
        }],
      });
      query.where[Op.and][0][Op.or]
        .push(models.sequelize.literal(`"customer->addresses"."address_line_1" ILIKE '%${search}%'`));
    }
  }],
});
```

{% endcode %}

{% hint style="info" %}
[Displaying extensive logs](https://docs.forestadmin.com/documentation/how-tos/settings/display-extensive-logs) can be useful to see how the query is executed.
{% endhint %}


---

# 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/woodshop/how-tos/search-on-a-smart-field-with-joints.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.
