У меня есть специальный драгоценный камень, который создает запрос AR с входными данными, поступающими из экземпляра elasticsearch.
# record_ids: are the returned ids of the ES results
# order: is the order of the of the ids that ES returns
search_class.where(search_class.primary_key => record_ids).order(order)
Прямо сейчас реализация заключается в том, что я встраиваю строку заказа непосредственно в переменную order
, поэтому она выглядит так: ["\"positions\".\"id\" = 'fcdc924a-21da-440e-8d20-eec9a71321a7' DESC"]
Это работает нормально, но выдает предупреждение об устаревании, которое в конечном итоге не будет работать в rails6.
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "\"positions\".\"id\" = 'fcdc924a-21da-440e-8d20-eec9a71321a7' DESC". Non-attribute arguments will be disallowed in Rails 6.0. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql()
Поэтому я попробовал несколько разных подходов, но все они не увенчались успехом.
order = ["\"positions\".\"id\" = 'fcdc924a-21da-440e-8d20-eec9a71321a7' DESC"]
# Does not work since order is an array
.order(Arel.sql(order))
# No errors but only returns an ActiveRecord_Relation
# on .inspect it returns `PG::SyntaxError: ERROR: syntax error at or near "["`
.order(Arel.sql("#{order}"))
# .to_sql: ORDER BY [\"\\\"positions\\\".\\\"id\\\" = 'fcdc924a-21da-440e-8d20-eec9a71321a7' DESC\"]"
order = ['fcdc924a-21da-440e-8d20-eec9a71321a7', ...]
# Won't work since its only for integer values
.order("idx(ARRAY#{order}, #{search_class.primary_key})")
# .to_sql ORDER BY idx(ARRAY[\"fcdc924a-21da-440e-8d20-eec9a71321a7\", ...], id)
# Only returns an ActiveRecord_Relation
# on .inspect it returns `PG::InFailedSqlTransaction: ERROR:`
.order("array_position(ARRAY#{order}, #{search_class.primary_key})")
# .to_sql : ORDER BY array_position(ARRAY[\"fcdc924a-21da-440e-8d20-eec9a71321a7\", ...], id)
Я как бы застрял, так как рельсы заставляют аргументы атрибутов в будущем, и у меня нет возможности отказаться от этого. Поскольку order
представляет собой массив, сгенерированный кодом, и у меня есть полный контроль над значениями, мне любопытно, как я могу это реализовать. Может быть, у кого-то была эта проблема, прежде чем дать какую-то полезную информацию или идею?
order[0]
? - person Sebastian Palma   schedule 28.11.2019AR.where(id: some_ids)
не гарантирует порядок, и я хочу применить заказ из эластичного результата. В этом примере я использовал только одну запись в массиве, но их также может быть много. - person Denny Mueller   schedule 28.11.2019Arel.sql(order.join(', '))
? - person Sebastian Palma   schedule 28.11.2019order
. - person Sebastian Palma   schedule 28.11.2019.order
.order = ["\"positions\".\"id\" = '430a37b5-953e-476c-ad9e-e7a8b9dd8722' DESC", "\"positions\".\"id\" = 'cf989afa-eabe-4bd2-a8db-79d03eb6fe44' DESC"]
даст вам to_sqlORDER BY \"positions\".\"id\" = '430a37b5-953e-476c-ad9e-e7a8b9dd8722' DESC, \"positions\".\"id\" = 'cf989afa-eabe-4bd2-a8db-79d03eb6fe44' DESC
- person Denny Mueller   schedule 28.11.2019