Можно сделать область для обработки сложных режимов, вот пример из одного проекта, над которым я работаю:
scope :search_by_name, lambda { |q|
if q
case q
when /^(.+),\s*(.*?)$/
where(["(last_name LIKE ? or maiden_name LIKE ?) AND (first_name LIKE ? OR common_name LIKE ? OR middle_name LIKE ?)",
"%#{$1}%","%#{$1}%","%#{$2}%","%#{$2}%","%#{$2}%"
])
when /^(.+)\s+(.*?)$/
where(["(last_name LIKE ? or maiden_name LIKE ?) AND (first_name LIKE ? OR common_name LIKE ? OR middle_name LIKE ?)",
"%#{$2}%","%#{$2}%","%#{$1}%","%#{$1}%","%#{$1}%"
])
else
where(["(last_name LIKE ? or maiden_name LIKE ? OR first_name LIKE ? OR common_name LIKE ? OR middle_name LIKE ?)",
"%#{q}%","%#{q}%","%#{q}%","%#{q}%","%#{q}%"
])
end
else
{}
end
}
Как вы можете видеть, я выполняю сопоставление регулярных выражений, чтобы обнаружить разные шаблоны и построить различные поиски в зависимости от того, что предоставляется. В качестве дополнительного бонуса, если ничего не предоставлено, он возвращает пустой хеш, который фактически равен where(true)
, и возвращает все результаты.
Как упоминалось в другом месте, БД не может индексировать столбцы, когда с обеих сторон используется подстановочный знак, такой как %foo%
, поэтому это может привести к замедлению на очень больших наборах данных.