модуль 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 Создаёт 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 приведет к преобразует все имена столбцов в верблюжью нотацию — это также переопределяет :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> Кроме того, сериализуемый объект будет передан во второй параметр Proc. Это позволяет добавлять произвольные элементы в результирующий документ, учитывая контекст сериализуемого объекта. Используя замыкание, созданное Proc, #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>
Чтобы вызвать любые дополнительные Proc, используйте :procs. Proc передаётся модифицированная версия хеша опций, переданного в 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
# File activerecord/lib/active_record/serializers/xml_serializer.rb, line 174
def to_xml(options = {}, &block)
XmlSerializer.new(self, options).serialize(&block)
end
© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.