James N
James N

Reputation: 533

Rails Administrate - Customize has_many

I am working with the administrate gem. I have a collection of users and am showing a has_many relationship in that user dashboard.

Right now, my user_dashboard looks like

class UserDashboard < Administrate::BaseDashboard
  # ATTRIBUTE_TYPES
  # a hash that describes the type of each of the model's fields.
  #
  # Each different type represents an Administrate::Field object,
  # which determines how the attribute is displayed
  # on pages throughout the dashboard.
  ATTRIBUTE_TYPES = {
    ...
    sub_items: Field::HasMany.with_options(limit: 10)
  }

Right now, this works by default, but the problem is it is showing all of the sub_items for a user which would normally be fine, but I am trying to only show the has_many relationship if it has a certain type to it. For example, by default I do not want to show all of the user.sub_items, I only want to show the user.sub_items.where(category: [arr_of_options], sub_category: [arr_of_options])

Right now, I have tried

Does anyone know how I could only show certain has_many objects in an administrate dashboard?

Upvotes: 3

Views: 4351

Answers (1)

pablobm
pablobm

Reputation: 2066

To show only a specific scope of a has_many relationship, do the following.

First, on the model class, create a new has_many relationship, parallel to the original one, with a different name, that has the desired scope. For example, in the example app bundled with the Administrate source code, I added a new_england_orders association to the Customer model:

 class Customer < ApplicationRecord
   has_many :orders, dependent: :destroy
+  has_many :new_england_orders, ->{ where(address_state: %w{VT NH MA CT ME RI}) }, class_name: "Order"
   belongs_to :country, foreign_key: :country_code, primary_key: :code
   has_many :log_entries, as: :logeable

Second, add this relationship to your dashboard (possibly replacing the original one), and make sure to add the class_name option so that Administrate knows what dashboard to use for it:

     lifetime_value: Field::Number.with_options(prefix: "$", decimals: 2),
     name: Field::String,
     orders: Field::HasMany.with_options(limit: 2, sort_by: :id),
+    new_england_orders: Field::HasMany.with_options(limit: 2, sort_by: :id, class_name: 'Order'),
     log_entries: Field::HasManyVariant.with_options(limit: 2, sort_by: :id),
     updated_at: Field::DateTime,
     kind: Field::Select.with_options(collection: Customer::KINDS),

Your new, scoped association should now appear on your dashboard.

Upvotes: 4

Related Questions