2012-01-20 17 views
18

Mam ruby ​​hasz, który chciałbym renderować przy użyciu RABL. Hash wygląda mniej więcej tak:Renderowanie prostego hasza Ruby z RABL

@my_hash = { 
    :c => { 
     :d => "e" 
    } 
} 

Próbuję czynią to z pewnym kodem Rabl:

object @my_hash => :some_object 
attributes :d 
node(:c) { |n| n[:d] } 

ale ja dostaję {"c":null}

Jak mogę uczynić to z RABL?

Odpowiedz

22

Obecnie Rabl nie gra zbyt dobrze ze skrótów. Byłem w stanie obejść to poprzez konwersję mojego skrótu do formatu OpenStruct (który używa bardziej przyjaznego dla RABLa zapisu kropek). Korzystanie swój przykład:

your_controller.rb

require 'ostruct' 
@my_hash = OpenStruct.new 
@my_hash.d = 'e' 

your_view.rabl

object false 
child @my_hash => :c do 
    attributes :d 
end 

wyniki

{ 
    "c":{ 
    "d":"e" 
    } 
} 
+0

Wygląda na to, że nie musisz używać notacji kropkowej, jeśli zawiniesz hasz w OpenStruct. https://github.com/nesquena/rabl/wiki/Rendering-hash-objects-in-rabl – jmosesman

2

Po określeniu takiego węzła uzyskuje się dostęp do obiektu @my_hash, do którego można uzyskać dostęp do atrybutów. Więc po prostu nieco zmienić swój kod, aby być:

object @my_hash 
node(:c) do |c_node| 
    {:d => c_node.d} 
end 

gdzie c_node jest zasadniczo przedmiotem @my_hash. To powinno dać ci to, czego oczekujesz (pokazane tutaj w JSON):

{ 
    "my_hash":{ 
     "c":{ 
     "d":"e" 
     } 
    } 
} 
+1

Niestety otrzymuję ten błąd 'Metoda niezdefiniowana 'D' dla: c: Symbol' stosując powyższy kod. – SundayMonday

+0

Czy '.d' jest poprawnym atrybutem' @ my_hash'? To musi być, w przeciwnym razie to, co próbujesz zrobić, nie jest możliwe. Przetestowałem ten kod na własną rękę i zadziałało dla poprawnego atrybutu obiektu. – iwasrobbed

2

Moja odpowiedź jest częściowo oparta na niżej wymienione strony:

adaptowany z tej strony:

http://www.rubyquiz.com/quiz81.html

require "ostruct" 

    class Object 
    def to_openstruct 
     self 
    end 
    end 

    class Array 
    def to_openstruct 
     map{ |el| el.to_openstruct } 
    end 
    end 

    class Hash 
    def to_openstruct 
     mapped = {} 
     each{ |key,value| mapped[key] = value.to_openstruct } 
     OpenStruct.new(mapped) 
    end 
    end 

Define to może do inicjowania i następnie dla każdej hash prostu umieścić to_openstruct i wysłać, że ponad do szablonu Rabl i zasadniczo zrobić to, co jnunn pokazuje w widoku.

4

RABL faktycznie może renderować hashy i tablice ruby ​​jako atrybuty, a nie jako obiekt główny.Tak więc, na przykład, jeśli tworzysz OpenStruct takiego dla obiektu głównego:

@my_object = OpenStruct.new 
@my_object.data = {:c => {:d => 'e'}} 

następnie można użyć tej Rabl szablonu:

object @my_object 

attributes :data 

A to render:

{"data": {"c":{"d":"e"}} } 

Alternatywnie, jeśli chcesz, aby :c była właściwością twojego obiektu głównego, możesz użyć "węzła", aby utworzyć ten węzeł, i wyrenderować skrót wewnątrz tego węzła:

# -- rails controller or whatever -- 
@my_hash = {:c => {:d => :e}} 

# -- RABL file -- 
object @my_hash 
# Create a node with a block which receives @my_hash as an argument: 
node { |my_hash| 
    # The hash returned from this unnamed node will be merged into the parent, so we 
    # just return the hash we want to be represented in the root of the response. 
    # RABL will render anything inside this hash as JSON (nested hashes, arrays, etc) 
    # Note: we could also return a new hash of specific keys and values if we didn't 
    # want the whole hash 
    my_hash 
end 

# renders: 
{"c": {"d": "e"}} 

Nawiasem mówiąc, jest to dokładnie taka sama, jak tylko za pomocą render :json => @my_hash w szynach, więc Rabl nie jest szczególnie przydatna w tej banalnej sprawy;) Ale to pokazuje, mechanikę i tak.

6

Czasami łatwo jest zrobić za dużo imho.

Jak o właśnie

render json: my_hash 

I podobnie jak magii możemy usunąć niektóre kodu!

29

Działa to dla dowolnych wartości skrótu.

object false 

@values.keys.each do |key| 
    node(key){ @values[key] } 
end 

pracował dla mnie za pomocą Rails 3.2.13 i Ruby 2.0.0-p195

+5

To zdecydowanie najbardziej elegancka odpowiedź, pochowana na dole. O wiele ładniejszy niż wymuszanie tworzenia 'OpenStruct'! – agmin

5

oferty Rabl w obiektach, ale nie wymagają szczególnej ORM. Tylko obiekty obsługujące notację kropkową. Jeśli chcesz użyć Rabl i wszystko masz to hash:

@user = { :name => "Bob", :age => 27, :year => 1976 } 

to trzeba najpierw włączyć skrótu do obiektu, który obsługuje dot notacji:

@user = OpenStruct.new({ :name => "Bob", :age => 27, :year => 1976 }) 

a następnie w szablonie Rabl traktować OpenStruct jak każdy inny obiekt:

object @user 
attributes :name, :age, :year 

Uważają, że jeśli wszystko robisz w aplikacji jest po prostu do czynienia z mieszań i nie ma obiektów lub baz danych zaangażowanych, może być lepiej z alternatywnym, bardziej niestandardowym programem budującym JSON, takim jak json_builder lub jbuilder.

wklejony z oficjalnej strony wiki na github Rabl za: https://github.com/nesquena/rabl/wiki/Rendering-hash-objects-in-rabl