2016-06-01 6 views
2

Ich verwende JBuilder Version 2.4.1 und Rails 4.2.6. Ich versuche ein komplexes Objekt zu JSON zu serialisieren. Der Code sieht wie folgt aus:Hash-Schlüssel automatisch in JBuilder in camelCase konvertieren

json.key_format! camelize: :lower 

json.data_object @foo 

@foo wie folgt aussieht:

{ 
    key: 'value', 
    long_key: 'value' 
} 

ich es erwarten als

{ 
    "dataObject": { 
    "key": "value", 
    "longKey": "value" 
    } 
} 

gemacht werden, sondern hält es den ursprünglichen Hash-Schlüssel, nur konvertieren data_object in camelCase

{ 
    "dataObject": { 
    "key": "value", 
    "long_key": "value" 
    } 
} 

Die Frage ist also: Was ist der richtige Weg, um Hash-Schlüssel mit JBuilder zu camelisieren?

Antwort

1

Wie Bryce hat erwähnt, verwendet Jbuilder to_json anstelle der Verarbeitung der Hash-Einstellung.

Eine einfache Lösung besteht darin, json.set! zu verwenden, um den Hash manuell zu serialisieren.

json.key_format! camelize: :lower 

json.data_object do 
    @foo.each do |key, value| 
    json.set! key, value 
    end 
end 

Obwohl, gibt es ein Problem: Wenn @foo leer ist, wird es überhaupt kein Objekt erstellen. Dies sind die Lösungen, die ich gefunden:

  1. definieren einen leeren Hash vor der Serialisierung

    json.key_format! camelize: :lower 
    
    json.data_object({}) # don't forget parentheses or Ruby will handle {} as a block 
    
    json.data_object do 
        @foo.each do |key, value| 
        json.set! key, value 
        end 
    end 
    
  2. eine leere Hash serialisiert, wenn die Quelle Variable leer

    json.key_format! camelize: :lower 
    
    if (@foo.empty?) do 
        json.data_object({}) 
    else 
        json.data_object do 
        @foo.each do |key, value| 
         json.set! key, value 
        end 
        end 
    end 
    

    Oder wenn Sie es vorziehen, Ihr Code flach

    json.key_format! camelize: :lower 
    
    json.data_object({}) if @foo.empty? 
    
    json.data_object do 
        @foo.each do |key, value| 
        json.set! key, value 
        end 
    end unless @foo.empty? 
    

Diese Lösungen funktionieren jedoch nicht, wenn Sie verschachtelte Objekte serialisieren müssen. Sie können durch monkeypatching das json Objekt innerhalb Jbuilder

def json.hash!(name, hash) 
    if hash.empty? 
    set! name, {} 
    else 
    set! name do 
     hash.each do |key, value| 
     if value.is_a?(Hash) 
      hash! key, value 
     else 
      set! key, value 
     end 
     end 
    end 
    end 
end 

tief Serialisierung erreichen Dann können Sie einfach json.hash! :data_object, @foo verwenden und das gewünschte Ergebnis zu erhalten.

2

Versuchen Sie diese global in Ihrer Anwendung (wie config/environment.rb zum Beispiel)

Jbuilder.key_format camelize: :lower 
+0

ich das gleiche Ergebnis zu erhalten. Es wird nicht Hash-Tasten camelisieren – Morozzzko

+0

Hmm, ich bin sicher, dass du das getan hast, aber du hast deinen Rails-Server neu gestartet, nachdem du das hinzugefügt hast? Sie sind auch sicher, dass jbuilder die JSON-Vorlage rendert und rails nicht einfach auf to_json zurückfällt? Möglicherweise müssen Sie in das Array von Hashes schauen, das in json.array http://www.rubydoc.info/github/rails/jbuilder/Jbuilder:array geladen ist! – beaorn

+0

Ja, ich habe es neu gestartet. Ich habe es sogar ein paar Mal gemacht, nur um sicher zu gehen. Ich bin mir nicht ganz sicher, ob ich es tun sollte. Ich würde mich freuen, wenn du das hier erklären könntest. Momentan habe ich einen Workaround mit Loops, den ich posten werde, wenn niemand eine bessere Lösung findet. – Morozzzko

1

Ich bin mir nicht sicher, ob das noch relevant ist. Aber für diejenigen, die für eine elegante Lösung suchen nach wie vor, empfehle ich auf einen Blick unter:

https://github.com/vigetlabs/olive_branch

Dieses Juwel lässt Ihre API-Benutzer weitergeben in und erhalten camelcase oder strich verrohrten Tasten, während die Rails app empfängt und produziert snake_cased.

Hier ist ein Beitrag, wo der Autor die Idee hinter diesem Juwel erklärt. https://www.viget.com/articles/introducing-olivebranch/

Hoffe, es hilft

Verwandte Themen