jbnunn
jbnunn

Reputation: 6355

Combine associated model data through foreign key with model in RoR

I have two models, Tweets and TweetsLocations, associated to each other with:

class Tweets < ActiveRecord::Base
  has_one :location, :primary_key => "twitter_message_id",
                     :foreign_key => "twitter_message_id"

And:

class TweetsLocation < ActiveRecord::Base
  belongs_to :tweet

If I load a Tweet, like @tweet = Tweet.find(1), I can see all the attributes of it with no problem. If I want to see the associated Location attributes, I can with @tweet.location, again with no problem.

But if I wanted to have a JSON array of all @tweet(s) that included the associated attributes from Locations--is this possible elegantly, or do I need to create a new array of "tweets_with_locations" with the tweets and attributes from my Locations model built into it?

Upvotes: 0

Views: 319

Answers (1)

Jordan Running
Jordan Running

Reputation: 106027

If you just want to include the TweetsLocation object in your JSON output you can use the :include option to as_json, e.g.:

@tweet = Tweet.find 1
@tweet.as_json :include => :location

If, however, you want to include the TweetsLocation's attributes as though they were attributes of the Tweet itself it's a little more complicated, but you have a couple options:

First, you can delegate the desired attributes to TweetsLocation, e.g.:

class Tweets < ActiveRecord::Base
  has_one :location, :primary_key => "twitter_message_id",
                     :foreign_key => "twitter_message_id"

  # if TweetsLocation has e.g. "name" and "coordinates" attributes
  delegate :coordinates, :name, :to => :location, :prefix => true
end

This way @tweet.as_json's output will have location_name and location_coordinates keys.

Secondly, you can override as_json to do massage the JSON output in any way you want, e.g.:

class Tweets < ActiveRecord::Base
  # ...

  def as_json options = {}
    # just merge all of TweetsLocation's attributes into the output
    attributes.merge(location.attributes).to_json options
  end
end

Upvotes: 1

Related Questions