1
votes

When defining associations in classes for Datamapper you don't seem to get the associated model data by default.

As an example:

class Song
    include DataMapper::Resource

    property :id,           Serial
    property :name,         String
    property :artist_id,    Integer

    belongs_to :artist
end

class Artist
    include DataMapper::Resource

    property :id,       Serial
    property :name,     String

    has n, :songs
end

Song.get(params[:id]).to_json

the song query doesn't perform a join with the artists table by default. How do you perform a join and get the Artist along with the Song in the above example? Querying either class separately works fine. Note, this is an existing db, not created via DataMapper.

Thanks in advance!

1

1 Answers

2
votes

I suspect that exactly what you are trying to do is currently not possible. With DataMapper, you can always easily load properties like the artist of a song, and it even uses what they call strategic eager loading, which is described here. But even if the property has already been loaded, it won't be included in the results returned by to_json.

So you are left with two alternatives:

  1. You can simply do some additional coding to compose a hash and then use to_json on it:
song = Song.get(params[:id])
json = song.attributes.merge({:artist => song.artist.attributes}).to_json
  1. You can include similar code in the Song class itself:
def to_json
  self.attributes.merge({:time_zone => self.time_zone.attributes}).to_json
end

If you work with #2, you also have to require 'json'.

Notice that it wouldn't be a good idea for DataMapper to make to_json work recursively. Otherwise you could end up with your whole database being returned :P