ruby on rails - example - Tienda de acceso para JSON anidado
save json data in postgres (1)
Tengo el modelo "Organización" que almacena toda la información relacionada con una organización. Existe un campo de tipo JSONB denominado "integraciones" que almacena información perteneciente a todas las integraciones de servicios externos que tiene una organización.
¿Cómo uso los accesores de la tienda para acceder a la información almacenada en JSON anidado, por ejemplo:
{
"mailchimp": {"api_key":"vsvsvef", "list_id":"12345"},
"sendgrid" : {"username":"msdvsv", "password":"123456"}
}
Sé que puedo acceder a mailchimp con los usuarios de la tienda de esta manera:
store_accessor :integrations, :mailchimp
¿Cómo puedo acceder fácilmente a la api_key de mailchimp?
Tienes razón, desafortunadamente store_accessor
no te permite acceder a claves anidadas. El motivo es que store_accessor
es básicamente un acceso directo que define los métodos de obtención y establecimiento:
# 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
Por lo tanto, sus opciones aquí son:
Para implementar su propio conjunto de métodos getter y setter manualmente:
# somewhere in your model def mailchimp_api_key self.mailchimp["api_key"] end def mailchimp_api_key= value self.mailchimp["api_key"] = value end
Esto resuelve un problema, pero tendría que escribir mucho de esto repetidamente para cada uno de los atributos anidados.
Para escribir su propio método auxiliar dentro del
ActiveRecord::Store::ClassMethods
, que definiría los mismos métodos de establecimiento y obtención dinámicamente para el conjunto de atributos que pasa.store_accessor
tomar la implementación básica de Railsstore_accessor
y agregar un Hash adicional iteración de claves para ello. No estoy seguro de si esto va a ser fácil, pero definitivamente sería interesante verlo como una joya.Salga de Rails y use el poder del soporte de tipo postgres
json
con algún códigoSQL
puro. Por ejemplo, puedes accederapi_key
atributoapi_key
con algo como eso:SELECT integrations->''mailchimp''->>''api_key'' as mailchimp_api_key FROM your_table_name;
Más información sobre las consultas de postgres json se puede encontrar here .