to_xml Hell

I am trying to create a custom response to a particular action being called in my controller and I am getting some really weird errors. I am running the rails 1.2 stable branch.

Here is the action in my controller: # GET /:year/:month/level/1 # GET /:year/:month/level/1.xml def show   @level = Level.find(params[:id])   @assets = @level.assests.find_by_year_month(params[:year], params[:month])

  respond_to do |format|     format.html # show.rhtml     format.xml { @level.to_xml :include => [ @assests ] }   end end

Here are the models: class Level < ActiveRecord::Base   has_many :assets end

class Asset < ActiveRecord::Base   belongs_to :level

  def self.find_by_year_month(year, month)     requested_date = Date.new(year.to_i, month.to_i, 1)     from = requested_date - 1     to = requested_date >> 1     find_with_deleted(:all,     :conditions => ["created_at < ? AND ( deleted_at IS NULL " +     "OR deleted_at < ? AND deleted_at > ? )", to, to, from ])   end end

I have written the find_by_year_month class method on the Asset model and it works great. When I run this action I get:

NoMethodError in LevelsController#show

You have a nil object when you didn't expect it! The error occurred while evaluating nil.macro

C:/../vendor/rails/activerecord/lib/active_record/xml_serialization.rb: 185:in `add_includes' C:/../vendor/rails/activerecord/lib/active_record/xml_serialization.rb: 180:in `each' C:/../vendor/rails/activerecord/lib/active_record/xml_serialization.rb: 180:in `add_includes' C:/../vendor/rails/activerecord/lib/active_record/xml_serialization.rb: 232:in `to_s' C:/../vendor/rails/activesupport/lib/active_support/vendor/builder/ xmlbase.rb:140:in `call' C:/../vendor/rails/activesupport/lib/active_support/vendor/builder/ xmlbase.rb:140:in `_nested_structures' C:/../vendor/rails/activesupport/lib/active_support/vendor/builder/ xmlbase.rb:60:in `method_missing' C:/../vendor/rails/activesupport/lib/active_support/vendor/builder/ xmlbase.rb:32:in `__send__' C:/../vendor/rails/activesupport/lib/active_support/vendor/builder/ xmlbase.rb:32:in `tag!' C:/../vendor/rails/activerecord/lib/active_record/xml_serialization.rb: 230:in `to_s' C:/../vendor/rails/activerecord/lib/active_record/xml_serialization.rb: 107:in `to_xml' C:/../app/controllers/schedules_controller.rb:23:in `show' C:/../app/controllers/schedules_controller.rb:21:in `show' C:/../app/controllers/application.rb:32:in `set_timezone'

Apparently, the error occurs on line 185 of C:/../vendor/rails/ activerecord/lib/active_record/xml_serialization.rb in `add_includes'

I can't figure out why this doesn't work. According to the post Jamis Buck made ( Buckblog: Web services, Rails-style ) this should work. Shouldn't it?

Any help would be greatly appreciated.

Nicholas

It’s

format.xml { @level.to_xml :include => [ :assests ] }

Use symbols, not variables. However, given what you are trying to do takes parameters, you may be best off defining your own to_xml on Asset as the to_xml document page suggests:

http://api.rubyonrails.org/classes/ActiveRecord/XmlSerialization.html#M000910

Jason

And of course no variable called @assests was set in the controller (although I see there is one called @assets). Uninitialized instance variables are treated as nil.

That was a type-o on my part. I did check to make sure the variables match in my code, but thanks for pointing that out.

- Nicholas

I have tried the approach you've suggested and it does work. I just thought you could pass an array in the :include array as Jamis did in his post.

def add   company = params[:person].delete(:company)   @company = Company.find_or_create_by_name(company[:name])   @person = @company.people.create(params[:person])

  respond_to do |wants|     wants.html { redirect_to(person_list_url) }     wants.js     wants.xml { render :xml => @person.to_xml(:include => @company) }   end end

The post was made on March 27th of 2006, so it easily could be invalid. Any thoughts?

Nicholas