thoughtbot / administrate

A Rails engine that helps you put together a super-flexible admin dashboard.
http://administrate-demo.herokuapp.com
MIT License
5.85k stars 1.11k forks source link

Enum value is not searchable #1943

Open khrisnagunanasurya-iav opened 3 years ago

khrisnagunanasurya-iav commented 3 years ago

Here is my model dashboard

class ClassroomDashboard < Administrate::BaseDashboard
  ATTRIBUTE_TYPES = {
    ...
    level: Field::Select.with_options(searchable: true, collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys }),
    ...
  }
...

but none of them are working, is this a bug or feature?

pablobm commented 3 years ago

Do you have SQL logs, to see what the search is actually trying to do?

hirokihokari commented 2 years ago

For anyone who got here later, as of 0.16.0, it seems to be doing "%<term>%" in WHERE LIKE clause. In above case, meaning it's searching with actual value. In above case, simply 0 would result in records for a1: 0.

And remember, if you define the enum without values assigned, e.g. enum [:a1, :a2, :b1, :b2, :c1, :c2] would generate values according to the ordinal; a1 would have 0, a2 would have 1, etc.

pablobm commented 2 years ago

The SQL is put together around these lines:

https://github.com/thoughtbot/administrate/blob/3739c6436feee531153f56b5d5650f9f6a6e8940/lib/administrate/search.rb#L87-L95

I think it should be possible to alter this to generate a different string in the case of an enum. This will probably require reading @scoped_resource in order to figure out which attribute is an enum and then provide the required SQL... I think!

Any brave soul willing to have a go at this and provide a PR? :slightly_smiling_face:

pablobm commented 1 year ago

Well, this is probably related to https://github.com/thoughtbot/administrate/issues/1939, and how Enums are a bit special.

littleforest commented 1 year ago

Here is an example of a customized search with enum where the enum field cannot be null:

# app/models/source_file.rb
class SourceFile < ApplicationRecord
  enum :status, [:pending, :completed]
end
# app/controllers/admin/source_files_controller.rb

module Admin
  class SourceFilesController < Admin::ApplicationController
    def filter_resources(resources, search_term:)
      Administrate::SourceFileSearch.new(
        resources,
        dashboard,
        search_term
      ).run
    end
  end
end

module Administrate
  class SourceFileSearch < Search
    private

    def query_template
      super
        .split(" OR ")
        .push("status = ?")
        .join(" OR ")
    end

    def query_values
      array = super
      term = array.first
      array + [SourceFile.statuses[term.parameterize(separator: "_")]]
    end
  end
end
emcoding commented 1 month ago

I am using enum hashes, and I created this workaround:

COLLECTION_FILTERS = {
    pending: ->(resources) { resources.where(status: :pending) },
    completed: ->(resources) { resources.where(status: :completed) },
    cancelled: ->(resources) { resources.where(status: :cancelled) },
  }.freeze

(And in the Attribute type:

status: Field::Select.with_options(
      searchable: true,
      searchable_fields: ["status"],
      collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys }),

Now I can search for "pending:". It's annoying that you need to add the : in the search field and it's not okay with more than a few statuses but yeah.