Rails: overriding as_json for dynamic value -- is there a smarter way?

Viewed 7806

I want to output a list of affiliate links, each tagged to identify the current user. It would be simple in HTML, but we're writing an API, so the output is JSON.

I have it working, but it seems overly complicated. Is this the best approach?

My model, AffiliateLink contains a field (the raw HTML of the link) that I'll transform and output on the fly by adding a token. I have a model method that produces the replacement -- it is non-trivial because we use multiple affiliates and each has a special transformation rule that this method knows about:

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

To get my correct link html in JSON I have done these things:

  • add attr_accessor :link_html to model
  • add an instance method to set the new accessor

...

def set_link_html(token)
  self.link_html = link_with_tracking_token(token)
end
  • override as_json in the model, replacing the original html_code with link_html

...

def as_json(options = {})
  super(:methods => :link_html, :except => :html_code)
end
  • iterate over the collection returned in the controller method to do the transformation

...

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

This seems like a lot of stuff to do just to get my teensy-weensy transformation done. Helpful suggestions (relating to this problem and not to other aspects of the code, which is in flux now) are welcome.

1 Answers
Related