确保Rails ActiveRecord中的JSONB中嵌套值的唯一性而没有self.class.exists?

问题描述 投票:2回答:1

通常,在保存之前,我们可以使用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都是名为config的JSONB列的所有顶级属性。

这导致:ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column users.api_key does not exist

是否存在以类似于self.class.exists?(key: value)的类似方式实现这一目标的Rails方式?是否有替代的低成本SQL查询使用?

ruby-on-rails ruby
1个回答
1
投票

有用于json(b)(Postgres Docs)的特殊运算符

->>将以字符串形式访问jsonb元素,即config->>api_key代替config.api_key

您应该可以执行此操作self.class.exists?('config->>api_key = ?', api_key)

© www.soinside.com 2019 - 2024. All rights reserved.