2012-08-04 8 views
12

Chcę wyświetlić listę linków partnerskich, z których każdy jest oznaczony w celu identyfikacji bieżącego użytkownika. Byłoby to proste w HTML, ale piszemy API, więc wyjście to JSON.Szyny: przesłonięcie wartości as_json dla wartości dynamicznej - czy istnieje mądrzejszy sposób?

Mam to działa, ale wydaje się zbyt skomplikowane. Czy to najlepsze podejście?

Mój model, AffiliateLink zawiera pole (nieprzetworzony kod HTML linku), który będę transformował i wyprowadzał w locie, dodając token. Mam metodę, która produkuje modelu wymiany - to nietrywialne, ponieważ używamy wielu oddziałów i każdy ma specjalną regułę transformacji, że metoda ta wie o:

def link_with_token(user_token) 
    # some gnarly code that depends on a lot of stuff the model knows 
    # that returns a proper link 
end 

Aby dostać mój prawidłowy łącze HTML w JSON I zrobili te rzeczy:

  • dodać attr_accessor :link_html modelować
  • dodać metodę instancji, aby ustawić nowy Accessor

.. .

def set_link_html(token) 
    self.link_html = link_with_tracking_token(token) 
end 
  • przesłanianie as_json w modelu, zastępując oryginalne html_code z link_html

...

def as_json(options = {}) 
    super(:methods => :link_html, :except => :html_code) 
end 
  • iteracyjne nad kolekcji zwrócony w metodzie kontrolera do wykonaj transformację

...

def index 
    @links = Admin::AffiliateLink.all # TODO, pagination, etc. 

    respond_to do |format| 
    format.html # index.html.erb 
    format.json do 
     @links.each do |link| 
     link.set_link_html(account_tracking_token) 
     end 
     render json: @links 
    end 
    end 
end 

To wydaje się dużo rzeczy do zrobienia, aby dostać się mój teensy-weensy transformacja zrobić. Pomocne sugestie (odnoszące się do tego problemu, a nie do innych aspektów kodeksu, które teraz pojawiają się) są mile widziane.

+0

są opcje takie jak 'Rabl' lub po prostu faktycznie przy użyciu szablonu, aby pomóc uczynić swój' json' vs. przesłanianie 'metody as_json' bez dyskusji? – nowk

+0

Mam dabbled z RABL, ale wydaje się, że przedstawia więcej przeszkód (szczególnie w wyniku ograniczonej doc). Któregoś dnia po prostu przeczytam kod i wymyślę, jak go użyć. Na razie "as_json" wydaje się być dużo. –

Odpowiedz

18

1) Szybkie rozwiązanie problemu (jak wykazano here):

affiliate_links_controller.rb

def index 
    @links = Admin::AffiliateLink.all # TODO, pagination, etc. 

    respond_to do |format| 
    format.html # index.html.erb 
    format.json do 
     render json: @links.to_json(:account_tracking_token => account_tracking_token) 
    end 
    end 
end 

AffiliateLink.rb

# I advocate reverse_merge so passed-in options overwrite defaults when option 
# keys match. 
def as_json(options = {}) 
    json = super(options.reverse_merge(:except => :html_code)) 
    json[:link_with_token] = link_with_token(options[:account_tracking_token]) 
    json 
end 

2) Bardziej Hardcore rozwiązanie, jeśli jesteś naprawdę pisanie API:

  1. Zobacz this article opisując swój problem.
  2. Zob. the gem, które autorzy wykonali jako rozwiązanie.
  3. Zobacz this railscast na temat korzystania z klejnotu.

3) I wreszcie, rozwiązanie wygodne. Jeśli masz wygodną relację z modelem, jest to czyste:

Udając AffiliateLink belongs_to :user. I zakładając, że user_token jest dostępnym atrybutem użytkownika.

AffiliateLink.rb

# have access to user.user_token via relation 
def link_with_token 
    # some gnarly code that depends on a lot of stuff the model knows 
    # that returns a proper link 
end 

def as_json(options = {}) 
    super(options.reverse_merge(:methods => :link_with_token, :except => :html_code)) 
end 

affiliate_links_controller.rb

def index 
    @links = Admin::AffiliateLink.all # TODO, pagination, etc. 

    respond_to do |format| 
    format.html # index.html.erb 
    format.json do 
     render json: @links 
    end 
    end 
end 
+0

Dobra odpowiedź! Dzięki. –

+0

Ach, cieszę się, że mogłem pomóc – anxiety

+0

@ anxiety może warto wspomnieć o ActiveModel :: Serializers, które są ostatnim dodatkiem do Rails - patrz: https://blog.engineyard.com/2015/active-model-serializers, patrz także: http://railscasts.com/episodes/409-active-model-serializers – Tilo

Powiązane problemy