to_xml

Hey all,

I have some problems creating a rendered xml file

this is my source

  def show_friends     @profile = Profile.find(user)       @list = @profile.send('friends').find(:all, :limit => 20, :order => 'RAND()')       @checkin = Checkin.find(:last, :conditions => {:profile_id => @list})       @place = @checkin.place     respond_to do |format|           format.html {render}           format.xml { render :xml => @list.to_xml(:dasherize => false)}         end   end

And this give as output

<profile> <login>wouter</login> <password>*</password> ... </profile>

What i want to do now is include the @place object in my xml

so like this:

<profile> <login>wouter</login> <password>*</password>   <place>     <latitude>... </latitude>     ..    </place> </profile>

I know i can do :include => [:place] but this include all the places from that person. I only want to get the last place where the user checked in ( @checkin = Checkin.find(:last, :conditions => {:profile_id => @list})       @place = @checkin.place) . So i really have to include this, but I have tried many things but nothing works.

How can i do this?

Thank you,

Wouter

I think creating a builder file in your views directory will be the easiest way to get exactly the xml output you want.

I think the most efficient way would be to create a has_one in the model with a unique name and use the conditions or order to get just one entry. I just tested this on one of my apps and it worked pretty well. I assume here that friends are just other profiles and a profile has many checkins? so you probably have something similar in profile.rb has_many :checkins has_many :places, :through => :checkins Add (I think anyways) has_one :last_checkin, :class_name => "CheckIn", :order => 'created_at' has_one :last_place, :through => :last_checkin, :source => :place

And you can just do

@profile.send('friends').find(:all, :limit => 20, :order => 'RAND()', include => :last_place) .to_xml(:include => :last_place)

* I put :last place in the finder to eager load, and again in the to_xml so that is is included in the xml.

Another way which doesn't require the model modified or a builder and is pretty ineffiecent for sql queries is

@items = @profile.send('friends').collect do |f|   h = f.attributes   h['place'] = f.checkins.last.place.attributes   h end @items.to_xml

Let me know if you still have problems and include the models. -Josh

Hey Josh,

Thank you for your answer. I have implemented this in my model and controller and it works half. I will try to explain what the problem is.

This is my code from profile.rb

  has_many :place   has_many :checkin   has_one :last_checkin, :class_name =>"Checkin", :order => "created_at desc"   has_one :last_place, :through => :last_checkin, :source => :place

so i get the last_checkin from my database sorted by latest, last_place is then the place source from my last_checkin. when i get the to_xml and have as include :last_checkin i see the latest checkin

<last_checkin> <created_at type="datetime">2009-07-31T19:00:49Z</created_at> <device nil="true"/> <id type="integer">100</id> <places_id type="integer">59</places_id> <profile_id type="integer">3</profile_id> <status/> </last_checkin>

my places_id is here 59 so i want to get the source of this place. But now when i do :last_place i get this

<last_place> <address nil="true"/> <category nil="true"/> <city>Namur</city> <country>BE</country> <created_at type="datetime">2009-07-31T18:43:50Z</created_at> <id type="integer">57</id> <latitude type="float">50.4641</latitude> <longitude type="float">4.86043</longitude> <name>Namen</name> <updated_at type="datetime">2009-07-31T18:59:58Z</updated_at> <zip type="integer" nil="true"/> </last_place>

The id of place here is 57.

How does this comes and what am i doing wrong?

Thank you for your help!

Wouter

I took a look at my own code where I test implemented this and realized I have the same problem.

After watching SQL in the log and playing around in script/console I realized this was happening

If I type user.last_checkin.last_place I was getting the correct place if I typed user.last_place it wasn't sorting by created_at anymore in the query. The same thing is happening in the to_xml...

This feels a little dirty to me, but it seems to work fine. Just change the line in your model describing last_place to include the ordered at on checkin table.

has_one :last_place, :through => :last_checkin, :source => :place, :order => 'checkin.created_at desc'

and you should see the correct 'last_place'

Let me know if this worked for you.

Hey,

Thank you so much!

It worked

SOrry for late answer but forgot to answer!

THANK YOU!