Как обновить объект в Mongo с помощью неизменяемого класса case Salat
Я работаю над проектом со Scala, Salat, Casbah, Mongo, Play2, BackboneJS... Но в то же время можно узнать много нового... Со Scala все в порядке, но я нахожу свой код дерьмовый, и я действительно не знаю, что решение для его улучшения.
В основном мой пример использования:
- Объект MongoDB отправляется в JS-код браузера Play2
- Код JS обновляет данные объекта (через модель Backbone)
- JS отправляет обратно обновленный JSON на сервер (отправлено методом сохранения Backbone и получено Play с jp bodyparser)
- JSON, полученный Play, должен обновить объект в MongoDB
- Некоторые поля не должны обновляться по соображениям безопасности (идентификатор объекта, creationDate...)
Моя проблема - последняя часть. Я использую case-классы с Salat для представления объектов, хранящихся в MongoDB.
Я действительно не знаю, как обращаться с JSON, который я получаю из кода JS.
Должен ли я связать JSON с классом дел Salat, а затем попросить Mongo переопределить данные предыдущего объекта полностью новым объектом класса дел? Если да, то есть ли способ с Play2 или Salat автоматически создать обратно класс case из полученного JSON?
Должен ли я обрабатывать свои поля JSON индивидуально с $set для полей, которые я хочу обновить?
Должен ли я сделать элементы моего класса case изменчивыми? Это то, что мы на самом деле делаем в Java с Hibernate для примера: получить объект из БД, изменить его состояние и сохранить его. Но, похоже, это не самый подходящий способ делать со Scala...
Если кто-то может дать мне несколько советов для моего варианта использования, было бы неплохо, потому что я действительно не знаю, что делать:(
Изменить: я задал связанный вопрос здесь: Должен ли я представлять данные базы данных с неизменяемыми или изменяемыми структурами данных?
4 ответа
Вам нужны частичные линзы для обновления структуры данных JSON. http://dropbox.tmorris.net/media/doc/lenses.pdf
Salat обрабатывает JSON с помощью lift-json - см. https://github.com/novus/salat/wiki/SalatWithPlay2.
Сама программа Play использует Jerkson, что является еще одним способом декодирования объектов модели. Например, см. Http://blog.xebia.com/2012/07/22/play-body-parsing-with-jerkson/.
Не стесняйтесь создать небольшой пример проекта Github, который продемонстрирует вашу проблему, и отправьте его в список рассылки Salat по адресу https://groups.google.com/group/scala-salat для получения помощи.
На самом деле ответ довольно прост: я не знал, что в случае классов есть встроенный метод копирования, который позволяет копировать неизменяемый класс случаев при изменении некоторых данных.
У меня нет вложенных структур классов дел, но предложение Тони Морриса об использовании линз тоже кажется хорошим.
В вашем вопросе действительно две проблемы:
- Как использовать Play Salat.
- Как я могу предотвратить обновления для определенных полей.
Ответ на ваш первый вопрос лежит в документации Play Salat. На ваш второй вопрос можно ответить несколькими способами.
а. Когда обновление отправляется на сервер из Backbone, вы можете получить идентификатор объекта и найти его в базе данных. В этот момент у вас есть обе копии объекта. На этом этапе вы можете запустить бизнес-правило, чтобы убедиться, что отправитель не пытался изменить эти поля.
или же
б. Вы можете поместить некоторые из ваших полей в другой документ встроенного документа. Клиент будет иметь доступ к ним для целей рендеринга, но ваш API не позволит им вернуться в Mongo.
или же
с. Вы можете написать собственный запрос на обновление, который игнорирует поля, которые вы не хотите изменять.