Выбрать из базы данных указанный c JSON узел, используя Rails / AREL? - PullRequest
0 голосов
/ 21 апреля 2020

Представьте, что у меня есть таблица с именем books и столбец типа json с именем misc, в который были сохранены некоторые другие данные. Используя Rails / AREL, я бы хотел извлечь из всех книг только id и количество страниц (num_pages).

В psql Я могу сделать следующее:

SELECT id, misc->'num_pages' FROM books ;
  id   |   ?column?    
-------+---------------
 23562 | "220"
 22188 | "355"

(Примечание. Приведенный выше запрос дает те же результаты с -->, что и с ->).

Я ожидал, что это сработает:

pry> Book.select("id, misc->>'num_pages'")
  Book Load(1.7ms)  SELECT  id, etc-->'num_pages' FROM "books"
  Book Load(1.5ms)  SELECT  id, etc-->'num_pages' FROM "books"
=> #<Book::ActiveRecord_Relation:0x3ff7e934d8f4>

pry> Book.select("id, misc->'num_pages'")
  Book Load(1.1ms)  SELECT  id, etc->'num_pages' FROM "books"
=> [#<Book:0x00007fefd3c11a68 id: 23562>, #<Book:0x00007fefd3c116a8 id: 22188>]

... когда я удалить часть ->'num_pages', она возвращает все поле misc (так что я знаю, что почти работает):

pry> Book.select("id, misc")
  Book Load(0.9ms)  SELECT  id, etc FROM "books"
=> [#<Book:0x00007fefe4e99fb8
  id: 23562,
  etc:
   {"num_pages"=>"220",
...

1 Ответ

1 голос
/ 22 апреля 2020

Я не могу сделать это с .select, но .pluck работает в этой форме:

Book.pluck("id", "misc -> 'num_pages'")
  => [[23562, "220"], [22188,"355"]]

Однако это приведет к предупреждению об устаревании:

DEPRECATION WARNING: Dangerous query method (method whose arguments are used 
as raw SQL) called with non-attribute argument(s): "misc->'num_pages'". 
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().

Поэтому используйте Arel.sql() как предложено:

Book.pluck("id", Arel.sql("misc -> 'num_pages'"))
  => [[23562, "220"], [22188,"355"]]
...