Skip to content
coezbek edited this page Dec 17, 2021 · 4 revisions

Has Many Relationships in Table View

If you are showing a record in a table view in the resource admin which has a has_many relationship to another model which you want to display, you have the following options.

Let's assume that you have a has_many relationship between Author and Book, where one author could have written any number of books.

Add column with proc/&block

The following is a quick solution, with several drawbacks:

Trestle::resource(:author) do 

  table do
    column :name # Author's name
    column :number_of_books, ->(author) { author.books.count }
  end
end

Drawbacks:

  • This will cause N+1 queries, since for each author books.count is called separately.
  • This will disable sorting, because the proc is only evaluated for the instances shown on the current page.

Using a counter cache column

To get rid of the downsides you might want to use a counter cache column either via ActiveRecord counter_cache or counter_culture cem.

Once you have a counter_cache installed and thus have ..._count columns on your table you can do:

```ruby
Trestle::resource(:author) do 

  table do
    column :name # Author's name
    column :book_count
  end
end

Note:

Link to tab

If you followed the How-To on adding a tab for associated records you could link to this tab:

Trestle::resource(:author) do 

  table do
    column :name # Author's name
    column :number_of_books do |author|
      link_to author.books.count, author_admin_path(author, anchor: "!tab-book") 
    end
  end
end

If you used the counter caches described above, then your implementation would look like this:

Trestle::resource(:author) do 

  table do
    column :name # Author's name
    column :book_count, sort: :book_count do |author|
      link_to author.book_count, author_admin_path(author, anchor: "!tab-book")
    end
  end

end

Note:

  • You need the separate sort: :book_count when you use the proc/block to customize the rendering.