Administrate: Be able to search through a STI Field::BelongsTo

Created on 4 Oct 2018  路  8Comments  路  Source: thoughtbot/administrate

Hi,

I am using STI for authentication, so a base User, sub-classes Client, Host and Administrator.

One model which uses these classes is Appointment which is defined like below:

class Appointment < ApplicationRecord
  belongs_to :client
  belongs_to :host
end

Therefore, I have defined my Adminstrate dashboard like so:

class AppointmentDashboard < Administrate::BaseDashboard
  ATTRIBUTE_TYPES = {
    id: Field::Number,
    client: Field::BelongsTo
    host: Field::BelongsTo
  }
end

I just realised that we are missing the ability to search, which is super important. For example show all of Jim's Appointments.

Looking at at the documentation I came up with:

client: Field::BelongsTo.with_options(class_name: 'User', searchable: true, searchable_field: 'first_name')

However, this doesn't work because when creating the SQL query, it adds name of the field (client) to searchable_field, coming up with clients.first_name. I need it to be users.first_name because rails know that client is an STI. I've attached the query it produces , but it basically boils down to

WHERE (LOWER(CAST("clients"."first_name" AS CHAR(256))) LIKE '%lily%')

I attempted to add class_name: 'User' to with_options but that doesn't seem to have any effect.

I saw that there is a gem https://github.com/fishpercolator/administrate-field-type but that is for adding the type attribute to the parent, I need it the other way around.

And I doing something wrong?

Thanks for you help. Loving Administrate - provided me so many quick wins
Dave

feature search

All 8 comments

am having same issue with a project am working on

any ideas ?

I had a look today. There appear to be a couple of things that need to change in Administrate::Search for this to work. For now, I have been able to put these two methods together, which have helped me solve part of the problem:

    def association_for_attribute(attr)
      @scoped_resource.model.
        reflect_on_all_associations.
        detect { |assoc| assoc.name.to_s == attr.to_s }
    end

    def table_for_association(attr)
      association_for_attribute(attr).table_name
    end

Used then here:

     def query_table_name(attr)
       if association_search?(attr)
-        ActiveRecord::Base.connection.quote_table_name(attr.to_s.pluralize)
+        table_for_association(attr)
       else
         ActiveRecord::Base.connection.
           quote_table_name(@scoped_resource.table_name)

But there's still a bit more, where I have to make the JOIN and possibly the WHERE do the right thing too. I don't have more time today, so I'll leave it there for now. If anyone feels adventurous, I'd love some help here :-)

I have this issue as well, and it is potentially holding up going live with my application. Is it being worked on?

@pablobm, as you self-assigned, is this something you're actively working on?

Sorry, I got carried away with other things. I think I'll look into this next.

For an update: the roadmap has changed a bit, so I don't know when I'll be able to tackle this :disappointed:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MatthiasRMS picture MatthiasRMS  路  3Comments

sedubois picture sedubois  路  4Comments

conwayanderson picture conwayanderson  路  4Comments

ACPK picture ACPK  路  4Comments

steffenix picture steffenix  路  4Comments