2011-04-14 80 views
1

我已经更新了我的服务器红宝石1.9.2,这停止工作(轨3.0.6):to_xml包括在轨不起作用3.0.6红宝石1.9.2

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

回答

4

这是Rails的核心问题。发生的事情是,当包含乐器时,instrument_id属性正在增加。然后,当每个仪器被序列化时,XmlSerializer类根据Instrument类的定义确定该属性的类型,使用每个列的type属性。由于instrument_id属性在类定义中不存在,所以返回一个零对象,从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
0

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

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

请注意,包含与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

+0

我刚刚测试了这一点,它给了我一个不同的错误:“未定义的方法'宏”的零:NilClass”。我可以通过创建一个视图来轻松解决这个问题,但我仍然想知道这里出了什么问题。感谢您的输入! – 2011-04-14 11:41:10

+0

您宁可为连接表创建模型,而不是视图。你也可以试试':include => {:musicians_instruments =>:instruments}'。 – dombesz 2011-04-14 12:14:40

0

这里是一个解决方法是奏效了我。

我转换的所有活动记录对象中的属性调用哪个固定的问题,对我来说

@musicians = @ musicians.map {哈希| A | a.attributes}

@ musicians.to_xml