I have set enum task_status as:
class ConfirmedTask < ApplicationRecord
enum task_status: {pending: 1, complete: 2}
end
Now i have to search all task with pending status with search params 'pend'. I am using pg_search for search but it doesnot work with enum so i want to query using LIKE query:
ConfirmedTask.where('task_status like ?', '%pend%')
But this gives me error
ActiveRecord::StatementInvalid (PG::UndefinedFunction: ERROR: operator does not exist: integer ~~ unknown) LINE 1: ...asks".* FROM "confirmed_tasks" WHERE (task_status like '%pen... ^ HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
any suggestions?
Enums are normally stored as integers in the database. The mapping to a label is done on application level. The database is not aware of the labels.
This means you'll have to figure out what labels match your criteria on application level. Then convert them into their integer values (which are used in the database). One way to achieve this would be to use grep
in combination with a regex that matches your requirements.
# find the matching labels
labels = ConfirmedTask.task_statuses.keys.grep(/pend/i)
# convert them into their integer values
values = labels.map(&ConfirmedTask.task_statuses)
# create your query
ConfirmedTask.where('task_status IN (?)', values)
Somewhat easier would be to drop the label to value translation and let Rails figure this out. This can be done by passing the array of labels to a normal where
call (with a non-SQL string argument).
# find the matching labels
labels = ConfirmedTask.task_statuses.keys.grep(/pend/i)
# pass labels to `where` and let Rails do the label -> integer conversion
ConfirmedTask.where(task_status: labels)
I'm not 100% sure if an array of strings is allowed as the where
condition of an enum attribute. The documentation uses symbols. If the above does not work, map the strings into symbols with .map(&:to_sym)
.