# Searchable Associations

Search-as-you-type association pickers for Rails 8, without wiring Select2 or Tom Select.

![Searchable Associations screenshot](https://avohq.io/assets/addons/searchable-associations/searchable-associations-02bd0b4ac0fe9676a3de83de463a7ad865b30aaee2431e40e034890ddcf49bc4.png)

- Price: $15/month
- Gem: `gem "avo-advanced_search"`
- Web page: https://avohq.io/addons/searchable-associations
- Pricing: https://avohq.io/pricing.md

Let people find the right record by typing a few letters, instead of scrolling a dropdown with a thousand options in it, and skip wiring Select2 or Tom Select into your Rails 8 forms to get there. [Searchable Associations](https://docs.avohq.io/4.0/associations/searchable.html) turns the standard `<select>` on an Avo association field into a search-as-you-type picker: set `searchable: true` on a `belongs_to`, `has_one`, or `has_many` field and the picker queries records as the user types. It reuses the `self.search` block already defined on the target resource, so most pickers light up with no extra config.

```
# app/avo/resources/project.rb
class Avo::Resources::Project < Avo::BaseResource
  def fields
    # Boolean form: reuse the target resource's self.search
    field :user, as: :belongs_to, searchable: true

    # Hash form: full control over the query and each row
    field :members, as: :has_many, searchable: {
      query: -> { query.ransack(name_cont: q).result },
      item: -> { { title: record.name, description: record.email } },
      enabled: -> { current_user.admin? }
    }
  end
end
```

When you need more control, pass a hash instead of `true`: a `query:` proc runs as the user types so you decide exactly which records match, `item:` shapes each row's `title` and `description`, and `enabled:` can switch searchable mode on per user, falling back to a plain select for everyone else. Polymorphic `belongs_to` works too, with each type routing to its own resource's search. That is a search input wired to your data, built for large tables and vetted across many apps, so your agent sets one option instead of generating it.

## What you get

- Search-as-you-type picker that replaces the standard `<select>` on association fields
- Works on `belongs_to`, `has_one`, and `has_many` fields, including polymorphic `belongs_to`
- Boolean form (`searchable: true`) reuses the `self.search` block already defined on the target resource
- Hash form takes a `query:` proc that runs as the user types, so you decide exactly which records match
- `item:` proc to render each row's `title` and `description` in the dropdown
- `enabled:` boolean or proc to turn searchable mode on or off per user, falling back to a plain select
- Show default results before any typing by branching on `q.blank?` inside the `query:` proc

## Why it pays off

- Drop `searchable: true` on a field and a usable picker ships this afternoon, instead of building autocomplete, debouncing, and a JSON endpoint over a sprint.
- It reuses the resource search you already configured, so one definition powers every picker pointing at that record.
- It is built for the breadth of real apps, large tables, polymorphic targets, per-user gating, the cases a picker built for one app does not need yet.
- Every Avo release makes it better: the picker gains improvements and keeps working through upgrades, and fixes reach your app with bundle update.

## Questions

### Do I need Select2 or Tom Select for this?

No. The picker ships with the add-on, built on Stimulus, and searches on the server as the user types, so there is no jQuery, no JavaScript package to install, and no JSON endpoint to write. If you need a searchable select in your customer-facing forms, outside your Avo app, Tom Select is still a good choice there.

### Does it work on Rails 8?

Yes. Avo 4 and its add-ons run on Rails 8; this site runs on them. The picker is part of Avo's own form, so there is nothing to bridge between your asset pipeline, importmap or jsbundling setup and a third-party select library.

### Which association fields can be searchable?

`belongs_to`, including polymorphic, `has_one`, `has_many` and `has_and_belongs_to_many`, plus the record picker in the attach modal. Each one can reuse the target resource's search or take its own `query:` for that one field.

Included in bundles: Essentials ($75/month)
