Associations
One of the most amazing things about Ruby on Rails is how easy it is to create Active Record associations between models. We try to keep the same simple approach in Avo too.
Declare an association field in your resource's def fields and Avo renders it appropriately on each view. A belongs_to shows up as a link to the associated record (and a dropdown or search input on forms), while has_one, has_many, and has_and_belongs_to_many render as panels below the resource's fields, with attach, detach, and create controls.
# app/avo/resources/post.rb
class Avo::Resources::Post < Avo::BaseResource
def fields
field :user, as: :belongs_to
field :comments, as: :has_many
end
end| Rails association | Avo field |
|---|---|
belongs_to | Belongs to |
has_one | Has one |
has_one :through | Has one |
has_many | Has many |
has_many :through | Has many |
has_and_belongs_to_many | Has and belongs to many |
WARNING
It's important to set the inverse_of as often as possible to your model's association attribute.
If the target resource has too many records for a dropdown, make the picker search-as-you-type with Searchable associations.
Nested association forms (the nested option on those fields) require the avo-nested gem in addition to your usual Avo gems. Use the same source and credentials as for your other private Avo gems; see Gem server authentication.
The model association has to exist first
An association field renders a Rails association — it doesn't create one. field :comments, as: :has_many needs a matching has_many :comments on the model; without it there is nothing for Avo to load.
When the association panel loads and the model has no such association, Avo raises Avo::MissingAssociationError, naming the model, the field, and the declaration to add:
Failed to find the :comments association on Post while rendering the :comments field.
Define `has_many :comments` on Post, or update the Avo field to use an association that exists.Two things cause it: the model is genuinely missing the association, or the field name doesn't match the one the model declares (field :comments against a has_many :post_comments). Fix whichever side is wrong — add the association to the model, or point the field at the name that exists.
INFO
The array field is the exception. It renders a panel of records that deliberately isn't backed by an association, so it never raises here.
Common options
Association fields share most of their options. Each ✓ links to that option's documentation on the field's page.
For exact defaults, callback locals, and validation rules, consult the API reference for Belongs to, Has one, Has many, or Has and belongs to many.
| Option | Belongs to | Has one | Has many | HABTM |
|---|---|---|---|---|
searchable | ✓ | ✓ | ✓ | ✓ |
attach_scope | ✓ | ✓ | ✓ | ✓ |
use_resource | ✓ | ✓ | ✓ | ✓ |
scope | – | – | ✓ | ✓ |
name | – | – | ✓ | ✓ |
description | – | ✓ | ✓ | ✓ |
loading | – | ✓ | ✓ | ✓ |
linkable | – | ✓ | ✓ | ✓ |
reloadable | – | ✓ | ✓ | ✓ |
nested | – | ✓ | ✓ | ✓ |
attach_using | – | – | ✓ | ✓ |
attach_fields | – | ✓ | ✓ | – |
discreet_pagination | – | – | ✓ | ✓ |
per_page | – | – | ✓ | ✓ |
hide_search_input | – | – | ✓ | ✓ |
hide_filter_button | – | – | ✓ | ✓ |
link_to_child_resource | ✓ | – | ✓ | ✓ |
A few options belong to a single field type: polymorphic_as + types, polymorphic_help, can_create, allow_via_detaching, and link_to_record are all on belongs_to. attach_fields only persists its values on :through associations, where there's a join record to write to — see has_many and has_one.
Show or hide the association buttons
The attach, detach, create, destroy, and actions buttons on association panels are controlled through the target resource's policy methods. Find out more on the authorization page.
Single Table Inheritance (STI)
Give the parent model and each of its subclasses their own resource, and set self.model_class on each child resource to its subclass. The Single Table Inheritance guide walks through the full setup.
Link to child resource when using STI
A parent resource with self.link_to_child_resource = true opens each record on its Index in the resource for the record's class, so a spouse on the Person Index opens in Avo::Resources::Spouse. The belongs_to, has_many and has_and_belongs_to_many fields take a link_to_child_resource option that makes the same choice for their links. See open records in their own resource for how the field and resource settings combine.
Add custom labels to the associations' pages
You might want to change the name that appears on the association page. For example, if you're displaying a team_members association, your users will default see Team members as the title, but you'd like to show them Members.
You can customize that using fields localization.
