Search code examples
ruby-on-railsrails-admin

rails_admin search through nested belongs_to association


I have a model:

class TenantReference < ActiveRecord::Base
  include TenantReferenceAdmin
  belongs_to :tenant, inverse_of: :reference
  default_scope { eager_load(:tenant) }
end

and a Tenant model:

class Tenant < ActiveRecord::Base
  default_scope { eager_load(:user) }
  belongs_to :user
end

and a User model:

class User < ActiveRecord::Base
  has_many :tenants, :foreign_key => :user_id, class_name: 'Tenant'
end

and finally a TenantReferenceAdmin rails admin file:

module TenantReferenceAdmin
  extend ActiveSupport::Concern

  included do
    rails_admin do
      list do
        field :tenant do
          filterable true
          queryable true
          searchable [ :first_name, :last_name]
        end
    ...

what I'm trying to achieve is that in the tenantreference admin page the user can search TenantReference objects by the first_name or last_name of the user through their Tenant reference.

This configuration is producing a postgresql query like:

SELECT  "tenant_references"."id" AS t0_r0, .... "tenants"."id" AS t1_r0, ......
FROM "tenant_references" LEFT OUTER JOIN "tenants" ON "tenants"."id" = "tenant_references"."tenant_id" 
WHERE ((tenants.first_name ILIKE '%query%') 
  OR (tenants.last_name ILIKE '%query%') 
ORDER BY tenant_references.id desc LIMIT 20 OFFSET 0)

which doesn't work, because first/last_name are actually fields of user, not of tenant.

how could I fix this?

Thanks,


Solution

  • The problem seems to be that rails admin only adds JOIN to the query if the current model has a direct link (has_many, has_one ...) to the other model to search in. and it joins it if the corresponding field is marked as queryable true.

    so I changed adding to the references model this line:

    has_one :user, through: :tenant

    I then created an invisible list field:

        field :user do
          visible false
          queryable true
          searchable [{User => :first_name}, {User => :last_name}]
        end
    

    that can be searched upon, but it's not shown in the list.

    this has solved the issue, I don't consider this ideal as I had to modify my model in order to be able to perform rails_admin search, when rails_admin could have handled this situation without changing the code. But for now I can live with this