Подтвердить что ты не робот

Как сделать работу Backbone и MongoDB без проблем?

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

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

В документации Backbone упоминается, что вы можете указать другое имя, чем 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']);, но это именно то, чего я хочу избежать!

4b9b3361

Ответ 1

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

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

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

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

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

    return response;
}

Или что-то вроде этого. Аналогично, поскольку Backbone будет отправлять id как JSON с "id", ваш сервер может взять это и "перевести" его другим способом.

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

idAttribute: '_id',

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

    return response;
}

Все, что лучше всего подходит для вас.: -)

Ответ 2

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

MongoModel = Backbone.Model.extend({
    // this handle conversion between the mongo _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;
    }
});

Ответ 3

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

$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, поскольку больше клиентов может захотеть подключиться к нему.

Ответ 4

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

items.find.to_a.map do |item|
  frombsonid(item)
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 вы будете использовать разные синтаксис и методы, но я считаю, что вполне возможно повторить это.

Ответ 5

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

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

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