我已将服务器更新为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'
有什么迹象表明我做错了什么?
有关答案 0 :(得分:4)
这是Rails的核心问题。发生的事情是,当包含Instruments时,会添加instrument_id
属性。然后,当序列化每个Instrument时,XmlSerializer类使用每个列的type属性,根据Instrument类的定义确定该属性的类型。由于类定义中不存在instrument_id
属性,因此返回一个nil对象,从Ruby 1.9开始,它没有type
属性,Rails依赖于该属性。
(我不认为您链接的主题中的补丁有效 - 但我在下面提供的补丁确实如此。)
有两种方法可以解决这个问题:
instrument_id
(好主意)。
render :xml => @musicians.to_xml( :include => { :instruments => { :except => :instrument_id } } )
--- 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
答案 1 :(得分:0)
我想如果您使用的是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
嵌套包含。
答案 2 :(得分:0)
这是一个为我解决问题的解决方法。
我使用为我修复问题的属性调用将所有活动记录对象转换为哈希
@musicians = @ musicians.map {| a | a.attributes}
@ musicians.to_xml