Rails 5 виден как несколько частичных строк - PullRequest
0 голосов
/ 11 декабря 2018

Скажем, у меня есть область видимости, подобная этой:

scope :by_templates, ->(t) { joins(:template).where('templates.label ~* ?', t) }

Как я могу получить несколько шаблонов с t, как это?

Document.first.by_templates(%w[email facebook])

Этот код возвращает эту ошибку.

PG::DatatypeMismatch: ERROR:  argument of AND must be type boolean, not type record
   LINE 1: ...template_id" WHERE "documents"."user_id" = $1 AND (templates...

1 Ответ

0 голосов
/ 11 декабря 2018

PostgreSQL позволяет применять логический оператор ко всему массиву значений, используя конструкцию op any(array_expr) :

9.23.3.ЛЮБОЙ / НЕКОТОРЫЙ (массив)

expression operator ANY (array expression)
expression operator SOME (array expression)

Правая часть - это выражение в скобках, которое должно давать значение массива.Левое выражение оценивается и сравнивается с каждым элементом массива с использованием заданного operator, что должно привести к логическому результату.Результат ANY является «истинным», если получен какой-либо истинный результат.Результат равен «ложь», если истинный результат не найден (включая случай, когда массив имеет нулевые элементы).

PostgreSQL также поддерживает синтаксис конструктора массива для создания массивов:

array[value, value, ...]

Удобно, если ActiveRecord расширяет заполнитель как список с разделителями-запятыми, когда значение является массивом.

Объединение этих значений дает нам:

scope :by_templates, ->(templates) { joins(:template).where('templates.label ~* any(array[?])', templates) }

Кроме того, если вы используете оператор регулярного выражения без учета регистра (~*) в качестве сравнения без учета регистра (т. Е. Реального сопоставления с шаблоном регулярного выражения), вы можете использовать upper вместо этого:

# Yes, this class method is still a scope.
def self.by_templates(templates)
  joins(:template).where('upper(templates.label) = any(array[?])', templates.map(&:upcase) }
end

Затем вы можете добавить индекс к templates на upper(label), чтобы ускорить процесс и избежать возможных проблем с случайными метасимволами регулярных выражений в templates.Я склонен использовать верхний регистр для такого рода вещей из-за странностей, лежащих 'ß'.upcase, являющихся 'SS', но 'SS'.downcase, являющихся 'ss'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...