2015-06-07 10 views
13

Ho il modello "Organizzazione" che memorizza tutte le informazioni relative a un'organizzazione. Esiste un campo di tipo JSONB denominato "integrazioni" che memorizza le informazioni relative a tutte le integrazioni di servizi esterni di un'organizzazione.Accessor di archiviazione per JSON annidato

Come faccio a utilizzare metodi di accesso negozio per accedere alle informazioni memorizzate nel nidificato JSON, ad esempio:

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

so di poter accedere MailChimp con negozi di accesso in questo modo:

store_accessor :integrations, :mailchimp 

Come posso accedere facilmente al api_key di mailchimp?

risposta

17

Hai ragione, purtroppo store_accessor non consente l'accesso alle chiavi annidate. La ragione è che store_accessor è fondamentalmente solo una scorciatoia che definisce metodi getter e 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 

Così, le vostre opzioni sono:

  1. per implementare il proprio insieme di metodi getter e 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 
    

    Questo risolve un problema, ma dovresti scrivere molto questo ripetutamente per ciascuno degli attributi annidati.

  2. Per scrivere il proprio metodo di supporto all'interno di ActiveRecord::Store::ClassMethods modulo che definisca gli stessi setter e getter metodi in modo dinamico per l'insieme degli attributi si passa. Dovreste prendere l'implementazione di base di Rails store_accessor e aggiungere un ulteriore hash key iteration ad esso. Non sono sicuro se questo sarà facile, ma sarebbe sicuramente interessante vedere condiviso come una gemma.

  3. Lasciare Rails stesso e utilizzare il potere del supporto di tipo postgres json con un puro codice SQL. Ad esempio, è possibile accedere attributo api_key con qualcosa di simile:

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

    Altro su Postgres query JSON può essere trovato here.