Как сделать так, чтобы идентификаторы Backbone и MongoDB работали без проблем?

Мое приложение Backbone взаимодействует с REST API, созданным поверх MongoDB, поэтому «естественные» идентификаторы моих объектов действительно являются MongoIDs , При сериализации в JSON они выглядят так:

"_id":{"$id":"505099e998dee4db11000001"}

В документации по магистрали упоминается, что вы можете указать другое имя, чем id для атрибута id вашей модели Backbone (используя idAttribute), так как строковые представления MongoIDs являются вложенными простое использование idAttribute: '_id' не помогает напрямую использовать JSON.

Есть ли способ обойти это, кроме переписывания атрибутов на стороне сервера?

Обновление:

Вот что я делаю на стороне сервера:

$m = new Mongo();
$posts = $m->mydatabase->posts->find();

$out = array();

foreach ($posts as $post) {
    $out[] = $post;
}

echo json_encode($out);

Я знаю, что могу сделать что-то вроде $post['id'] = (string) $post['_id']; unset($post['_id']);, но это именно то, чего я хочу избежать!

12 голосов | спросил julien_c 12 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 12 Sep 2012 18:32:34 +0400 2012, 18:32:34

5 ответов


0

Это звучит как хороший пример для parse()

Поскольку ваш Mongo JSON заканчивает отправку:

"_id":{"$id":"505099e998dee4db11000001"}

Почему бы не использовать анализ Backbone для правильного пространства имен входящих данных?

parse: function(response) {
    response.id = response._id['$id'];
    delete response._id;

    return response;
}

Или как то так. Точно так же, поскольку Backbone будет отправлять идентификатор как JSON с идентификатором «id», ваш сервер может принять это и «перевести» его другим способом.

Если вы хотите использовать другой атрибут id , _id, вы просто замените приведенный выше синтаксический анализ на этот код:

idAttribute: '_id',

parse: function(response) {
    response._id = response._id['$id'];

    return response;
}

Все, что работает лучше для вас. : -)

ответил jmk2142 12 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 12 Sep 2012 19:02:31 +0400 2012, 19:02:31
0

Лучше выполнить преобразование в браузере, чтобы вы перенесли вычисления с сервера. Таким образом, вы хотите создать базовую MongoModel, а затем вы можете расширяться из MongoModel вместо Backbone.Model.

MongoModel = Backbone.Model.extend({
    // this handle conversion between the mongo's _id and backbone id
    // this is best done on the client side to alleviate server load
    //_id : { "$oid" : ... } <--> id
    parse : function (response) {
        response.id = response._id.$oid;
        delete response._id;
        return response;
    },
    toJSON : function () {
        var
            json = Backbone.Model.prototype.toJSON.apply(this);
        json._id = {'$oid':json.id};
        delete json.id;
        return json;
    }
});
ответил MICHAEL PERMANA 3 +04002013-10-03T02:34:32+04:00312013bEurope/MoscowThu, 03 Oct 2013 02:34:32 +0400 2013, 02:34:32
0

Глядя на различные предлагаемые варианты, я обнаружил, что проще всего сделать то, чего вы хотите избежать. (Использование parse работает, хотя)

$m = new Mongo();
$posts = $m->mydatabase->posts->find();

$out = array();

foreach ($posts as $post) {
    // populate an id field
    $post['id']=$post['_id']->{'$id'},
    $out[] = $post;
}

echo json_encode($out);

Сохранение $post['_id'], если вы хотите, чтобы ваша модель отправляла его обратно при синхронизации. Я предпочитаю исправлять API, так как к нему может подключиться больше клиентов.

ответил Jason Prawn 1 FebruaryEurope/MoscowbFri, 01 Feb 2013 16:56:51 +0400000000pmFri, 01 Feb 2013 16:56:51 +040013 2013, 16:56:51
0

В Ruby я могу сделать следующее:

items.find.to_a.map do | item |
  frombsonid (пункт)
end.to_json

def frombsonid (obj) obj.merge ({'_ id' => obj ['_ id']. to_s}) end

и когда вы получите данные обратно, вы можете преобразовать строку в BSON :: ObjectId

def tobsonid(id) BSON::ObjectId.fromstring(id) end

Таким образом, идея состоит в том, чтобы заменить _id в каждом элементе строковой версией BSON :: ObjectId

В магистрали вы можете добавить

idAttribute: "_id", 

В PHP вы будете использовать другой синтаксис и методы, но я считаю, что это вполне возможно повторить.

ответил Dmitry 8 Jpm1000000pmTue, 08 Jan 2013 20:16:23 +040013 2013, 20:16:23
0

Ваш PHP-код - это REST API, с которым Backbone будет взаимодействовать, поэтому он должен обрабатывать абстракцию комплекса Mongo _id свойство для простой строки id, которую вы ищете. Это определенно работа API.

Backbone или любой другой пользователь вашего API не должен ничего знать о Mongo или _id.

Почему? Потому что, если бы вам пришлось переключиться с Mongo на какой-нибудь другой Db, где нет _id, то ваш API все еще хорош, потому что все, что когда-либо было раскрыт был id, который является универсальным. Таким образом, ваша оригинальная идея была на самом деле лучшей идеей (хотя вы хотели бы абстрагировать этот фрагмент кода во что-то, что можно повторно использовать для всех моделей, а не только для публикаций).

ответил jordanb 14 Jam1000000amWed, 14 Jan 2015 10:45:21 +030015 2015, 10:45:21

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132