Ask A Question

Notifications

You’re not receiving notifications from this thread.

JSON for Rails delegated attributes?

Brian Schwartz asked in Rails

In one of my Rails apps, I have the following architecture (as part of a current refactoring):

  • Contact (a lot of attributes common to all people)
    • Prospect (specific attributes to just prospects, delegates other attributes to contact
    • Lead (specific attributes to leads, delegates common attributes to contact

Both Prospect and Lead do the following (below). I've gone back and forth in testing on STI and / or MTI inheritance using acts_as gem, but this is actually the cleanest way for me for now (because leads and prospects are both contacts, but not mutually exclusive).

delegate :first_name, :last_name, :address_1, :address_2, :address_3, :zip, :city, :state, :email_address, :phone_number,
       :client_id, :unsubscribed, :original_list_id, :to => :contact

My code that isn't refactored yet renders prospect objects instances to json to use attributes in various client side needs. Using JSON the delegated attributes don't show up. I know you can explicitly declare methods in render :json declarations (and I do so elsewhere, on calculated columns), but this is clumsy for a lot of attributes in potentially multiple controllers. Using includes would require parsing them as separate object attributes (instead of these attributes appearing to be coming from Prospect or Lead).

I've looked into ActiveModel Serializer and it seems like it fits my needs, but I can't find a way to make it work with delegated attributes. Any ideas or suggestions would be appreciated...

Reply

Also, maybe another thought would be to override to_json for my Prospect and Lead models. Maybe I'll look there next (b/c ActiveModel Serializer could be overkill for this need).

Reply

I'm a big fan of just using jbuilder for this kind of stuff. It makes it rather easy to render out absolutely anything you want and is pretty much just like using the xml builder if you're familiar with that. No need to override to_json or anything. I believe it's intended to do pretty much the same thing as ActiveModel::Serializer, but jbuilder makes it feel more like a view that you're creating. You'll have full access to any instance variables set in the view and should be able to do what you want.

You'll just do this in your controller:

respond_to do |format|
  format.html
  format.json
end

And then create the view file as ACTION_NAME.json.jbuilder.

Reply

Chris, thanks. That worked great. Here's how I implemented this (which seems like it's working great).

@prospect.attributes.each do |attr_name, attr_value|
  json.set! attr_name, attr_value
end
@prospect.contact.attributes.each do |attr_name, attr_value|
  json.set! attr_name, attr_value unless attr_name == "id"
end
Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 82,329+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.