#ruby-on-rails #ruby #postgresql
Вопрос:
Во-первых, я не являюсь носителем английского языка, так что извините меня, если я допущу какие-либо ошибки, связанные с моим письмом.
Я начинаю как разработчик, и мне сказали, что я должен использовать запрос Postgresql для выполнения конкретной задачи в Ruby on Rails. Это и есть запрос:
ПОРЯДОК ПО array_position(МАССИВ[1, 2, 3], spree_products.id)
Цель состоит в том, чтобы показать представление с различными продуктами Spree (возможно, частью «МАССИВ[1,2,3 и т. Д.]») базы данных, упорядоченной таким же образом, как они помещены во входную форму администратора.
В любом случае, мой вопрос гораздо проще.
Я понимаю, что этот запрос является необработанным Postgresql, использующим функцию array_position
https://www.postgresql.org/docs/12/functions-array.html
Я просто хочу знать, как я могу реализовать такого рода необработанные запросы в Rails. Вероятно, это должно быть в файле .rb, но я действительно не понимаю, как, поскольку методы запросов, используемые в Rails (например,. order), гораздо чаще используются (это то, что я обычно использую), но, по-видимому, здесь я должен использовать необработанный Postgresql, смешанный с Rails.
Не могли бы вы привести мне несколько примеров и/или основную документацию, пожалуйста? Я знаю основы обоих языков, но я никогда не смешивал их таким образом, так что, вероятно, это сбивает меня с толку больше всего.
Спасибо вам всем.
Ответ №1:
вы можете создать область и использовать arel
функцию обертывания массива array_position
class Product < ApplicationRecord
scope :order_ids, ->(arr_ids) {
order(Arel.sql("array_position(ARRAY#{arr_ids}, id::integer)"))
}
end
теперь вы можете запросить, как показано ниже
Product.order_ids([3,2,1])
Product.where(active: true).order_ids([3,2,1]).limit(10)
# ...
Комментарии:
1.
"array_position(ARRAY#{arr_ids}, id::integer)"
является уязвимостью для инъекции SQL и должна использоваться только в том случае, еслиarr_ids
это не пользовательский ввод.2. Это можно решить, добавив
ActiveRecord::Base::sanitize_sql(arr_ids)
, если возможно, что они являются пользовательским вводом.