Обеспечить уникальность вложенного значения в JSONB в Rails ActiveRecord без self.class.exists? - PullRequest
2 голосов
/ 09 октября 2019

Обычно мы можем использовать self.class.exists?(api_key: api_key), чтобы проверить, имеет ли какая-либо другая строка в таблице значение перед сохранением:

def set_api_key
  self.api_key ||= loop do
    api_key = SecureRandom.hex(24)
    break api_key unless self.class.exists?(api_key: api_key)
  end
end

Но в этом примере api_key на самом деле является значением дляСтолбец JSONB с именем config:

class User < ApplicationRecord
  before_validation :set_api_key, on: [:create]
  validates :api_key, presence: true, uniqueness: true

  store_accessor :config, :status, :plan, :api_key

  def set_api_key
    self.api_key ||= loop do
      api_key = SecureRandom.hex(24)
      break api_key unless self.class.exists?(api_key: api_key)
    end
  end
end

Предположим, :status, :plan, :api_key - все атрибуты верхнего уровня столбца JSONB с именем config.

Thisприводит к: ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column users.api_key does not exist

Есть ли хитрый Rails-способ достижения этого аналогично тому, как работает self.class.exists?(key: value)? Есть ли недорогой SQL-запрос для использования вместо этого?

1 Ответ

1 голос
/ 10 октября 2019

Существуют специальные операторы для использования с json (b) ( Postgres Docs )

->> будет обращаться к элементу jsonb в виде строки, т.е. config->>api_key вместо config.api_key

Вы должны быть в состоянии сделать это self.class.exists?('config->>api_key = ?', api_key)

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