Подтвердить что ты не робот

Храните аксессуар для вложенного JSON

У меня есть модель "Организация", которая хранит всю информацию, связанную с организацией. Существует поле типа JSONB с названием "интеграция", в котором хранится информация, относящаяся ко всем внешним сервисам, которые организация имеет.

Как использовать средства доступа к хранилищу для доступа к информации, хранящейся в вложенном JSON, например:

{
 "mailchimp": {"api_key":"vsvsvef", "list_id":"12345"},
 "sendgrid" : {"username":"msdvsv", "password":"123456"}
}

Я знаю, что могу получить доступ к mailchimp с помощью аксессуаров магазина, таких как:

store_accessor :integrations, :mailchimp

Как я могу легко получить доступ к api_key mailchimp?

4b9b3361

Ответ 1

Вы правы, к сожалению store_accessor не позволяет вам входить в вложенные ключи. Причина в том, что store_accessor - это просто ярлык, который определяет методы getter и setter:

# here is a part of store_accessor method code, you can take a look at
# full implementation at
# http://apidock.com/rails/ActiveRecord/Store/ClassMethods/store_accessor
_store_accessors_module.module_eval do
  keys.each do |key|
    # here we define a setter for each passed key
    define_method("#{key}=") do |value|
      write_store_attribute(store_attribute, key, value)
    end

    # and here goes the getter
    define_method(key) do
      read_store_attribute(store_attribute, key)
    end
  end
end

Итак, ваши варианты:

  • Чтобы реализовать свой собственный набор методов getter и setter вручную:

    # somewhere in your model
    def mailchimp_api_key
      self.mailchimp["api_key"]
    end
    
    def mailchimp_api_key= value
      self.mailchimp["api_key"] = value
    end
    

    Это решает проблему, но вам придется много раз писать много для каждого из вложенных атрибутов.

  • Чтобы написать собственный метод помощника внутри модуля ActiveRecord::Store::ClassMethods, который будет динамически определять те же методы настройки и метода getter для набора атрибутов, которые вы проходите. Вам нужно будет выполнить базовую реализацию Rails store_accessor и добавьте к нему дополнительную итерацию хеш-ключей. Не уверен, что это будет легко, но определенно будет интересно видеть, что общий как драгоценный камень.

  • Оставьте Rails самостоятельно и используйте поддержку типа postgres json с некоторым чистым кодом SQL. Например, вы можете получить доступ к атрибуту api_key с чем-то вроде этого:

    SELECT integrations->'mailchimp'->>'api_key' as mailchimp_api_key FROM your_table_name;
    

    Подробнее о postgres json-запросах можно найти здесь.