2010-12-14 11 views
19

Mam na początku dziwną sytuację w modelu danych, więc może całe moje podejście jest błędne. Oto co robię:RoR zagnieżdżone: uwzględnij, aby uwzględnić pod-zasoby w to_xml/to_json

Mam klasę o nazwie Bird i prostej klasy o nazwie Color. Koncepcyjnie, każdy ptak ma dwa do wielu powiązań z kolorem, jeden dla męskich kolorów i jeden dla żeńskich kolorów. Sposób, w jaki to zrobiłem, to użycie modelu łączenia o nazwie BirdColoration, który należy do ptaka i koloru, i ma dodatkowe pole logiczne, aby stwierdzić, czy kolor jest dla mężczyzny czy kobiety. Zatem każdy ptak ma w rzeczywistości wiele związków z BirdColoration, a także z to_many do Color: through BirdColoration. Jeśli to brzmi rozsądnie, kontynuuj czytanie. W przeciwnym razie przestań i powiedz mi, dlaczego jest źle!

Muszę być w stanie rzucić stół dla ptaków jako json. Poprzednio, gdy każdy ptak miał tylko jedno do wielu skojarzeń z kolorami, mogłem po prostu użyć: include, aby dołączyć kolory każdego ptaka do zrzutu json. Teraz włączam BirdColorations do zrzutu, ale nadal muszę dostać się do samych modeli kolorów. Mogłabym osobno uwzględnić kolory i kolory każdego ptaka, a następnie dopasować je podczas analizy, ale wolałbym po prostu uwzględnić kolor każdego koloru bezpośrednio. Coś takiego, jak na przykład powyższe nie działa, jednak nie działa. Myślę, że to powinno być możliwe. Czy ktoś może wskazać mi właściwy kierunek postępowania?

Na razie uwzględnię kolor i kolor każdego ptaka oddzielnie i dopasujemy je do parsowania. Przynajmniej wiem, że to zadziała.

Dzięki!

Odpowiedz

51

Znalazłem odpowiedź here. Składnia opcji: include w to_xml i to_json jest inna niż w metodzie znajdowania ActiveRecord. Aby dołączyć zasoby zagnieżdżone w ten sposób, przekazujesz hasz zamiast tablicy. Poprawna metoda dla mnie wygląda:

 format.json { render :json => @birds.to_json(:include => {:bird_colorations => {:include => :color}, :seasons => {}, :habitats => {}, :image_holders => {}}) } 

Porównaj z tym w moim pytaniu, aby zobaczyć różnicę. W przypadku zasobów, dla których nie chcesz uwzględniać pod-zasobów, po prostu przekazuj puste hash jako wartość dla symbolizowanej nazwy.

Żyj i ucz się!

+1

Chciałbym zagłosować na to więcej !! Dzięki! – brutuscat

+0

ja też @brutuscat. Uratowałem mój bekon! – Rots

+0

Kod w pytaniu wygląda o wiele czystszy, jest to sprzeczne z intuicją. Zwłaszcza, że ​​jeśli nie masz koloru zagnieżdżającego bird_colorations, przykład pytań będzie działał. Dziękujemy za przesłanie rozwiązania. Railsy powinny to naprawić ... – thatmiddleway

2

Jeśli masz złożoną strukturę JSON, lepiej zastąpić model serializable_hash lub as_json w swoim modelu, niż spróbować zrobić wszystko przez render :json.

Więc coś

def serializable_hash(options = nil) 
    options ||= {} 
    bird = {:name => name, ...} 
    bird[:seasons] = seasons.serilizable_hash 
    bird[:colors] = ... # whatever complex logic you want to get to the colors 
    bird 
end 

Obie funkcje wystarczy powrócić hash.

+0

Dzięki! Przyjrzę się temu. Jeśli jestem zadowolony z wyników uzyskiwanych z renderowania: json, czy jest jakikolwiek inny powód do nadpisania tych metod (może wydajność)? Wszystkie inne rzeczy są równe, mój instynkt polega na tym, aby wbudowana funkcja zajmowała się dla mnie rzeczami. – CharlieMezak

+0

Nie sądzę, aby uzyskać wzrost wydajności, ponieważ render json wywołuje as_json/serializable_hash w tle.To po prostu dobra filozofia projektowania zwana "grubymi modelami, cienkimi kontrolerami", najbardziej elegancko omawiana tutaj: http://stackoverflow.com/questions/2550376/rails-skinny-controller-vs-fat-model-or-should-i- make-my-controller-anoreksję – icecream

Powiązane problemy