У меня есть модель activerecord с некоторыми атрибутами, которые мне нужно переопределить при создании xml для API. Инструкции here, описывающие, как писать пользовательский метод to_xml
, отлично подходят для этого.Переопределение ActiveRecord :: Base # to_xml для родителя, но не для детей
Проблема, с которой я сталкиваюсь, заключается в том, что модель находится на вершине довольно глубокой системы отношений, и это будет огромная работа, чтобы вручную указать генерацию xml всех потомков. Есть ли способ передать управление Builder для отношений, чтобы он мог автоматически создавать свой xml так же, как прежде, чем мне пришлось переопределить?
Вот пример того, что я хотел бы сделать:
class IHaveMyOwnXML < ActiveRecord::Base
has_many :widgets
def to_xml(options = {})
options[:indent] ||= 2
xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
xml.instruct! unless options[:skip_instruct]
xml.level_one do
xml.tag!(:second_level, 'content')
end
xml.pick_up_where_you_left_off! widgets
end
end
Очевидно pick_up_where_you_left_off!
не существует. Я хочу, чтобы xml для widgets
, который должен быть введен в этот момент в документе xml, выглядящий точно так, как если бы я не сделал переопределение, и вызвал IHaveMyOwnXML # to_xml (: include =>: widgets).
Возможно ли это? Или, как только вы переопределяете ActiveRecord # to_xml, выполняете ли вы затем вручную кодирование xml-продукции для произвольно глубоких вложенных отношений AR?
Я пробовал первое предложенное предложение, и, хотя оно само по себе, я не могу сказать, как вводить отношение, когда я вхожу в свой собственный метод to_xml. ни один из следующих работ:
xml.household do
xml.id id
xml.accounts accounts
end
xml.household do
xml.id id
xml << accounts.to_xml # also w/ (opts.merge(:builder => xml))
end
Первый раз не дает объект рубин реф (<accounts>#<Account:0x10abb5250></accounts>
). Второй вводит полный XML-документ с узлом household
в качестве корня и объявлением xml.
Спасибо. Первоначальное тестирование, похоже, указывает на то, что это сработает. Я уже пробовал это, но он путался с начальными аргументами, отправленными на верхнем уровне - 'foo.to_xml (: include => {: bar =>: car})' - это получало исключение, потому что Bar doesn ' t 'has_any: bars'. Рассмотрев ваш ответ, я понял, что я не должен использовать: include, когда я определяю to_xml вручную b/c. Я уже явно делаю 'xml.bar bar' – Avram
Хорошо, получается, что хотя это нормально, это неполный. Я не могу понять, как вставить отношение в xml, как только use_custom_xml? True. Я обновил вопрос с дополнительной задачей. – Avram