Spec-Zone.ru › Ruby on Rails 4.2

модуль ActiveRecord::Serialization

Включённые модули:
ActiveModel::Serializers::JSON, ActiveModel::Serializers::Xml

Active Record Сериализация

Открытые методы экземпляров

serializable_hash(options = nil) Показать исходный код
# 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
Вызывает метод суперкласса
to_xml(options = {}, &block) Показать исходный код
# 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API