Spec-Zone.ru › Ruby on Rails 4.1

модуль 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) Показать исходный код

Создаёт 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.

Spec-Zone.ru

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