2010-09-15 16 views
16

Używam respond_with i wszystko jest podłączone, aby uzyskać prawidłowe dane. Chcę dostosować zwrócone formaty json, xml i foobar w sposób DRY, ale nie mogę się dowiedzieć, jak to zrobić, używając ograniczonych :only i :include. Te są świetne, gdy dane są proste, ale ze złożonymi znaleziskami, brakuje im tego, czego chcę.Jak dostosować odpowiedź to_json w Railsach 3

Powiedzmy mam post który has_many zdjęć

def show 
    @post = Post.find params[:id] 
    respond_with(@post) 
end 

Chcę zawierać obrazy z odpowiedzią, więc mogłem to zrobić:

def show 
    @post = Post.find params[:id] 
    respond_with(@post, :include => :images) 
end 

ale ja naprawdę nie chcesz wysłać cały obiekt obrazu wzdłuż, tylko adres URL. Poza tym, ja naprawdę chcę być w stanie zrobić coś takiego, jak również (pseudokod):

def show 
    @post = Post.find params[:id] 
    respond_with(@post, :include => { :foo => @posts.each.really_cool_method }) 
end 

def index 
    @post = Post.find params[:id] 
    respond_with(@post, :include => { :foo => @post.really_cool_method }) 
end 

... ale w suchej drodze. W starszych projektach rails użyłem konstruktorów XML, aby dostosować dane wyjściowe, ale replikować je w json, xml, html, co nie wydaje się właściwe. Muszę sobie wyobrazić, że kolejni guru umieścili coś w Rails 3, czego nie rozumiem dla tego typu zachowań. Pomysły?

Odpowiedz

7

Nie szyny 3 wbudowane w sposób, ale znalazłem wielki klejnot, który jest aktywnie utrzymuje on Rails 3: acts_as_api

+1

Ten link to 404. – lashleigh

+2

https://github.com/fabrik42/acts_as_api – coneybeare

21

można przesłonić as_json w modelu. Coś jak:

class Post < ActiveRecord::Base 
    def as_json(options = {}) 
    { 
     attribute: self.attribute, # and so on for all you want to include 
     images: self.images, # then do the same `as_json` method for Image 
     foo:  self.really_cool_method 
    } 
    end 
end 

i szyn dba o resztę przy użyciu respond_with. Nie do końca pewien co options zostanie ustawiony, ale prawdopodobnie opcje dajesz respond_with (:include, :only i tak dalej)

+2

Chce się zmienić as_json, as_xml, as_foobar wszystko w jednym miejscu. – scragz

+0

Tak, to naprawdę nie DRY – coneybeare

+0

'include' nie używa' as_json', to nie pomaga. – Meekohi

8

prawdopodobnie zbyt późno, ale znalazłem rozwiązanie bardziej DRY kopanie poprzez szyn docs. Działa to w moich krótkich testów, ale może potrzebować trochę szczypanie:

# This method overrides the default by forcing an :only option to be limited to entries in our 
# PUBLIC_FIELDS list 
def serializable_hash(options = nil) 
    options ||= {} 
    options[:only] ||= [] 
    options[:only] += PUBLIC_FIELDS 
    options[:only].uniq! 
    super(options) 
end 

To w zasadzie pozwala mieć listę pól, które są dopuszczone do publicznego API, i nie można przypadkowo narazić cały obiekt. Nadal możesz odsłonić określone pola ręcznie, ale domyślnie Twój obiekt jest bezpieczny dla .to_json, .to_xml, itp.

+0

Właściwie powinno to być domyślnie, gdy: only is not specified, w przeciwnym razie zmienia intencję użycia: only. Och, cóż, wciąż mój punkt jest taki sam. – Nerdmaster

+0

Zastępowanie serializable_hash działało lepiej dla mnie, aby dodać niektóre metody jako atrybuty w Rails 3.2.8, dziękuję! – Docunext

+0

To jest poprawna odpowiedź. Działa również w Railsach 4. – Meekohi

Powiązane problemy