Don Giulio
Don Giulio

Reputation: 3284

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,

Upvotes: 0

Views: 894

Answers (1)

Don Giulio
Don Giulio

Reputation: 3284

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

Upvotes: 2

Related Questions