Я нахожусь в процессе изучения Scala для нового проекта Rails. Я определил тип, который будет использоваться в ряде моих моделей, которые в основном можно рассматривать как набор «атрибутов». По сути, это просто оболочка для хэш-карты, которая делегирует ему большую часть своих обязанностей:
case class Description(attributes: Map[String, String]) {
override def hashCode: Int = attributes.hashCode
override def equals(other: Any) = other match {
case that: Description => this.attributes == that.attributes
case _ => false
}
}
Итак, я бы определил класс модели с Description
, что-то вроде:
case class Person(val name: String, val description: Description)
Однако, когда я сохраняю Person
с SalatDAO, я получаю документ, который выглядит следующим образом:
{
name : "Russell",
description:
{
attributes:
{
hair: "brown",
favourite_color: "blue"
}
}
}
Когда на самом деле мне не нужно вложение тега attributes
в тег description
- то, что я на самом деле хочу, это:
{
name : "Russell",
description:
{
hair: "brown",
favourite_color: "blue"
}
}
Я не пробовал, но я считаю, что мог бы заставить это работать, если бы заставил Description
расширить Map
вместо того, чтобы содержать его, но я бы предпочел нет, потому что Description
не тип Map
, это то, что имеет некоторое поведение Map
, а также другое его поведение, которое я добавлю позже. Композиция над наследованием и пр.
Итак, мой вопрос, как я могу сказать Salat (или Casbah, я на самом деле немного не уверен относительно того, что делает преобразование, поскольку я только начал их использовать), как сериализовать и десериализовать Description
учебный класс? В уроке касба здесь написано:
Также можно создавать собственные сериализаторы пользовательских типов и
deserializers. См. Пользовательские сериализаторы и десериализаторы.
Но эта страница, кажется, не существует. Или я поступаю неправильно? Есть ли действительно простой способ указать, что это то, что я хочу, аннотации или что-то в этом роде? Или я могу просто каким-то образом делегировать сериализацию в карту атрибутов?
РЕДАКТИРОВАТЬ: После просмотра источника помощника по преобразованию JodaTime я попробовал следующее, но пока не получилось заставить его работать:
import org.bson.{ BSON, Transformer }
import com.mongodb.casbah.commons.conversions.MongoConversionHelper
object RegisterCustomConversionHelpers extends Serializers
with Deserializers {
def apply() = {
super.register()
}
}
trait Serializers extends MongoConversionHelper
with DescriptionSerializer {
override def register() = {
super.register()
}
override def unregister() = {
super.unregister()
}
}
trait Deserializers extends MongoConversionHelper {
override def register() = {
super.register()
}
override def unregister() = {
super.unregister()
}
}
trait DescriptionSerializer extends MongoConversionHelper {
private val transformer = new Transformer {
def transform(o: AnyRef): AnyRef = o match {
case d: Description => d.attributes.asInstanceOf[AnyRef]
case _ => o
}
}
override def register() = {
BSON.addEncodingHook(classOf[Description], transformer)
super.register()
}
}
Когда я звоню RegisterCustomConversionHelpers()
, затем сохраняю Person
Я не получаю никаких ошибок, это просто не имеет никакого эффекта, сохраняя документ так же, как и всегда. Это также, кажется, довольно много для того, что я хочу.