to_xml include在rails 3.0.6 ruby​​ 1.9.2中不起作用

我已将我的服务器更新为ruby 1.9.2,这已停止工作(rails 3.0.6):

def index @musicians = Musician.includes(:instruments) render :xml => @musicians.to_xml( :include => :instruments ) end 

和模型:

 class Musician < ActiveRecord::Base has_and_belongs_to_many :instruments end class Instrument < ActiveRecord::Base has_and_belongs_to_many :musicians end 

我收到这个错误:

 undefined method `type' for nil:NilClass 

框架跟踪:

 activesupport (3.0.6) lib/active_support/whiny_nil.rb:48:in `method_missing' activerecord (3.0.6) lib/active_record/serializers/xml_serializer.rb:230:in `compute_type' activemodel (3.0.6) lib/active_model/serializers/xml.rb:22:in `initialize' activemodel (3.0.6) lib/active_model/serializers/xml.rb:75:in `new' activemodel (3.0.6) lib/active_model/serializers/xml.rb:75:in `block in serializable_attributes' 

我有什么问题吗?

也许这与以下内容有关: https : //rails.lighthouseapp.com/projects/8994/tickets/4840-to_xml-doesnt-work-in-such-case-eventselecttitle-as-tto_xml

这是Rails的核心问题。 发生的事情是,当包含Instruments时,会添加一个instrument_id属性。 然后,当序列化每个Instrument时,XmlSerializer类使用每个列的type属性,根据Instrument类的定义确定该属性的类型。 由于在类定义中不存在instrument_id属性,因此返回一个nil对象,从Ruby 1.9开始,它没有type属性,Rails依赖于该属性。

(我不认为你链接的线程中的补丁有效 – 但我在下面提供的补丁确实如此。)

有两种方法可以解决这个问题:

  1. 不要序列化instrument_id (好主意)。
     render :xml => @musicians.to_xml( :include => { :instruments => { :except => :instrument_id } } ) 
  2. 或补丁Rails核心(坏主意)。
     --- a/activerecord/lib/active_record/serializers/xml_serializer.rb 2011-04-20 15:01:10.000000000 -0700 +++ b/activerecord/lib/active_record/serializers/xml_serializer.rb 2011-04-20 15:00:42.000000000 -0700 @@ -226,8 +226,10 @@ class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc: def compute_type + Rails.logger.info("key: #{name}, hash: #{@serializable.class.columns_hash[name]}") type = @serializable.class.serialized_attributes.has_key?(name) ? - super : @serializable.class.columns_hash[name].type + super : @serializable.class.columns_hash[name].nil? ? + NilClass : @serializable.class.columns_hash[name].type case type when :text 

我想如果你正在使用HABTM关联,你应该有一个名为musicians_instruments的连接表,你必须包含嵌套的连接表。

 render :xml => @musicians.to_xml( :include => {:musicians_instruments =>{:include=>:instruments}} ) 

请注意,include与ActiveRecord关联不同。

更新

如果为连接表创建模型,则可以将has_and_belongs_to_many更改为has_many :through ,其使用频率更高并且相同。

 #musician.rb has_many :musicians_instruments has_many :instruments, :through=>:musicians_instruments #instrument.rb has_many :musicians_instruments has_many :musicians, :through=>:musicians_instruments 

这个应该与to_xml嵌套包含正常工作。

这是一个解决方法,为我做了诀窍。

我使用属性调用将所有活动记录对象转换为哈希,这为我解决了问题

@musicians = @ musicians.map {| a | a.attributes}

@ musicians.to_xml