модуль ActiveRecord::Serialization
Active Record Сериализация
Открытые методы экземпляров
# File activerecord/lib/active_record/serialization.rb, line 11
def serializable_hash(options = nil)
options = options.try(:clone) || {}
options[:except] = Array(options[:except]).map { |n| n.to_s }
options[:except] |= Array(self.class.inheritance_column)
super(options)
end # File activerecord/lib/active_record/serializers/xml_serializer.rb, line 174
def to_xml(options = {}, &block)
XmlSerializer.new(self, options).serialize(&block)
end Создаёт XML-документ для представления модели. Некоторые настройки доступны через options. Однако в более сложных случаях необходимо переопределить ActiveRecord::Base#to_xml.
По умолчанию создаваемый XML-документ будет включать инструкцию обработки и все атрибуты объекта. Например:
<?xml version="1.0" encoding="UTF-8"?> <topic> <title>The First Topic</title> <author-name>David</author-name> <id type="integer">1</id> <approved type="boolean">false</approved> <replies-count type="integer">0</replies-count> <bonus-time type="dateTime">2000-01-01T08:28:00+12:00</bonus-time> <written-on type="dateTime">2003-07-16T09:28:00+1200</written-on> <content>Have a nice day</content> <author-email-address>david@loudthinking.com</author-email-address> <parent-id></parent-id> <last-read type="date">2004-04-15</last-read> </topic>
Это поведение можно контролировать с помощью :only, :except, :skip_instruct, :skip_types, :dasherize и :camelize . Параметры :only и :except такие же, как и для метода attributes. По умолчанию имена всех столбцов приводятся к нижнему регистру с дефисами, но можно отключить эту настройку :dasherize до false. Установка :camelize в true приведет к преобразованию имён столбцов в верблюжью нотацию (camelCase) — это также переопределяет :dasherize. Чтобы не включать тип столбца в XML-вывод, установите :skip_types в true.
Например:
topic.to_xml(skip_instruct: true, except: [ :id, :bonus_time, :written_on, :replies_count ]) <topic> <title>The First Topic</title> <author-name>David</author-name> <approved type="boolean">false</approved> <content>Have a nice day</content> <author-email-address>david@loudthinking.com</author-email-address> <parent-id></parent-id> <last-read type="date">2004-04-15</last-read> </topic>
Для включения ассоциаций первого уровня используйте :include:
firm.to_xml include: [ :account, :clients ]
<?xml version="1.0" encoding="UTF-8"?>
<firm>
<id type="integer">1</id>
<rating type="integer">1</rating>
<name>37signals</name>
<clients type="array">
<client>
<rating type="integer">1</rating>
<name>Summit</name>
</client>
<client>
<rating type="integer">1</rating>
<name>Microsoft</name>
</client>
</clients>
<account>
<id type="integer">1</id>
<credit-limit type="integer">50</credit-limit>
</account>
</firm> Кроме того, сериализуемый объект будет передан в качестве второго параметра лямбда-выражения. Это позволяет добавлять в результирующий документ произвольные элементы, учитывающие контекст сериализуемого объекта. Используя лямбда-выражения, #to_xml может добавлять элементы, которые обычно находятся вне области модели — например, генерировать и добавлять URL-адреса, связанные с моделями.
proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
firm.to_xml procs: [ proc ]
<firm>
# ... normal attributes as shown above ...
<name-reverse>slangis73</name-reverse>
</firm> Для включения ассоциаций более глубоких уровней передайте хеш, как показано ниже:
firm.to_xml include: {account: {}, clients: {include: :address}}
<?xml version="1.0" encoding="UTF-8"?>
<firm>
<id type="integer">1</id>
<rating type="integer">1</rating>
<name>37signals</name>
<clients type="array">
<client>
<rating type="integer">1</rating>
<name>Summit</name>
<address>
...
</address>
</client>
<client>
<rating type="integer">1</rating>
<name>Microsoft</name>
<address>
...
</address>
</client>
</clients>
<account>
<id type="integer">1</id>
<credit-limit type="integer">50</credit-limit>
</account>
</firm> Для вызова любых методов модели используйте :methods:
firm.to_xml methods: [ :calculated_earnings, :real_earnings ] <firm> # ... normal attributes as shown above ... <calculated-earnings>100000000000000000</calculated-earnings> <real-earnings>5</real-earnings> </firm>
Для вызова дополнительных лямбда-выражений используйте :procs. Лямбда-выражения получают изменённую копию хеша опций, переданного в to_xml:
proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
firm.to_xml procs: [ proc ]
<firm>
# ... normal attributes as shown above ...
<abc>def</abc>
</firm> В качестве альтернативы вы можете передать объект билдера в качестве части вызова to_xml:
firm.to_xml do |xml|
xml.creator do
xml.first_name "David"
xml.last_name "Heinemeier Hansson"
end
end
<firm>
# ... normal attributes as shown above ...
<creator>
<first_name>David</first_name>
<last_name>Heinemeier Hansson</last_name>
</creator>
</firm> Как упоминалось выше, вы можете переопределить to_xml в своих подклассах ActiveRecord::Base, чтобы иметь полный контроль над генерируемым выводом. Общий вид этого переопределения:
class IHaveMyOwnXML < ActiveRecord::Base
def to_xml(options = {})
require 'builder'
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
end
end
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.