0
votes

What I try is to fetch some model objects from the database and serialize them to xml, but when including a specific (has_many) association I get the below error. The JSON serialization (to_json) works without a problem (with properties included too). Also the serialization of one object (XML and JSON). What could the problem be? (The model class doesn't override any XML serialization things, I am using Rails 3).

Here the command:
Entity.all.to_xml :include => :properties

and the dump:

NoMethodError: undefined method `macro' for nil:NilClass
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activesupport-3.0.1/lib/active_support/whiny_nil.rb:48:in `method_missing'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/serialization.rb:41:in `serializable_add_includes'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/serialization.rb:40:in `each'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/serialization.rb:40:in `serializable_add_includes'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/serializers/xml_serializer.rb:191:in `send'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/serializers/xml_serializer.rb:191:in `add_includes'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/serializers/xml_serializer.rb:186:in `add_extra_behavior'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activemodel-3.0.1/lib/active_model/serializers/xml.rb:103:in `serialize'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:134:in `call'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:134:in `_nested_structures'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:58:in `method_missing'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:31:in `tag!'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activemodel-3.0.1/lib/active_model/serializers/xml.rb:101:in `serialize'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/serializers/xml_serializer.rb:175:in `to_xml'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/associations/association_proxy.rb:218:in `send'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/associations/association_proxy.rb:218:in `method_missing'
... 5 levels...
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:134:in `call'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:134:in `_nested_structures'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:58:in `method_missing'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:31:in `tag!'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activemodel-3.0.1/lib/active_model/serializers/xml.rb:101:in `serialize'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activerecord-3.0.1/lib/active_record/serializers/xml_serializer.rb:175:in `to_xml'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activesupport-3.0.1/lib/active_support/xml_mini.rb:107:in `to_tag'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activesupport-3.0.1/lib/active_support/core_ext/array/conversions.rb:159:in `to_xml'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activesupport-3.0.1/lib/active_support/core_ext/array/conversions.rb:159:in `each'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activesupport-3.0.1/lib/active_support/core_ext/array/conversions.rb:159:in `to_xml'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:134:in `call'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:134:in `_nested_structures'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/builder-2.1.2/lib/builder/xmlbase.rb:58:in `method_missing'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activesupport-3.0.1/lib/active_support/core_ext/array/conversions.rb:158:in `__send__'
    from /home/kai/.rvm/gems/ruby-1.8.7-p302@projectx/gems/activesupport-3.0.1/lib/active_support/core_ext/array/conversions.rb:158:in `to_xml'

Update and solution

HoBlend was right ... one of the associations in the Entity model were not setup correctly, but not properties one.
In entity there was also an association to the User model:
belongs_to :created_by, :class_name => "User", :foreign_key => "created_by"
If you are used to working with ActiveRecord associations you see that the :foreign_key parameter is not valid here (it must be on the other side of the association, where it was also). Rails never complained about that parameter here and my tests all pass. But it made the XML serialization somehow fail (surprisingly not the JSON serialization).

Update of update

It seems there is a bug somewhere in ActiveRecord. Think of the following models:

class User < ActiveRecord::Base
  has_many :created_entities, :class_name => "Entity", :foreign_key => "created_by"
end

class Entity < ActiveRecord::Base
  belongs_to :created_by, :class_name => "User", :foreign_key => "created_by"
end

A created_by integer field is present in the Entity migration. It seems when you name the belongs_to association the same as the :foreign_key, then XML serialization breaks. As soon as I changed to belongs_to :creator, :class_name => "User", :foreign_key => "created_by" the serialization works as expected.

Update of the update of the update ;-)

This is already solved in Rails 3.0.3 (and I had 3.0.1). So what do I learn ... update the software first!

1

1 Answers

1
votes

Most likely the model relationships are not setup properly. Are you able to do:

e = Entity.find.first
e.properties

and have it return the associated objects?