сохранение модели магистрали, проверка не удалась

никакой поиск в Google не может решить мою путаницу, поэтому я решил задать вопрос здесь.

Я пытаюсь сохранить модель и использовать обратные вызовы успеха/ошибки. В документации по магистрали указано, что вы сохраняете свою модель следующим образом: model.save([attributes], [options]).

Я нигде не могу найти документацию, в которой рассказывается, как сохранить всю модель (т.е. без указания атрибутов), но наткнулся на этот вопрос, где во втором ответе говорится, что для сохранения всей модели вы можете сделать model.save({}, [options]).

Однако я пытаюсь это безрезультатно. Мой код ниже:

Базовая модель:

class Student extends Backbone.Model
  url: ->
    '/students' + (if @isNew() then '' else '/' + @id)

  validation:
    first_name:
      required: true
    last_name:
      required: true
    email:
      required: true
      pattern: 'email'

  schema: ->
    first_name:
      type: "Text"
      title: "First Name"
    last_name:
      type: "Text"
      title: "Last Name"
    email:
      type: "Text"
      title: "Email"

На мой взгляд, у меня есть следующая функция:

class Students extends CPP.Views.Base
  ...
  saveModel = ->
    console.log "model before", @model.validate()
    console.log "model attrs", @model.attributes
    @model.save {},
      wait: true
      success: (model, response) ->
        notify "success", "Updated Profile"
      error: (model, response) =>
        console.log "model after", @model.validate()
        console.log "model after is valid", @model.isValid()
        console.log "response", response
        notify "error", "Couldn't Update"

В первом console.log перед сохранением мне сообщают, что модель действительна, посредством ответа undefined. Если я действительно смотрю на модель, то вижу, что все три поля заполнены.

Точно так же в следующих двух журналах консоли в ошибках @model.validate() и @model.isValid() оба возвращают undefined и true соответственно. Однако ответ, который я получаю при попытке сохранить модель, Object {first_name: "First name is required", last_name: "Last name is required", email: "Email is required"}

Наконец, в console.log атрибутов моделей я получаю:

Object
  created_at: "2012-12-29 23:14:54"
  email: "[email protected]"
  first_name: "John"
  id: 2
  last_name: "Doe"
  type: "Student"
  updated_at: "2012-12-30 09:25:01"
  __proto__: Object

Это наводит меня на мысль, что когда я передал {} своей модели, она на самом деле пыталась сохранить атрибуты как нулевые, иначе почему бы еще возникла ошибка?

Может ли кто-нибудь указать, что я делаю неправильно? Я бы предпочел не передавать каждый атрибут отдельно в сохранение!

заранее спасибо


person Sarah Tattersall    schedule 30.12.2012    source источник


Ответы (2)


Из предложенного ответа Hui Zheng я изменил свой контроллер на своем сервере, чтобы вернуть студента в формате JSON.

Однако, чтобы найти настоящий источник проблемы, я прочитал документацию по магистрали при сохранении и обнаружил, что когда wait: true указывается в качестве опции, выполняется следующее:

if (!done && options.wait) {
        this.clear(silentOptions);
        this.set(current, silentOptions);
}

При дальнейшем исследовании ясности я обнаружил

clear: function(options) {
  var attrs = {};
  for (var key in this.attributes) attrs[key] = void 0;
  return this.set(attrs, _.extend({}, options, {unset: true}));
},

Из этого видно, что каждый атрибут очищается, а затем сбрасывается. Однако при очистке моей модели проверки, которые я написал, не пройдут (поскольку требуются first_name, last_name, email).

В документации backbone.validation нам говорят, что мы можем использовать параметр forceUpdate: true, поэтому я выбрал использовать это при сохранении моей модели. На данный момент я собираюсь предположить (хотя это может быть не очень хорошей практикой), что данные с сервера верны, поскольку они также были проверены.

Поэтому мой окончательный код:

saveModel = ->
  @model.save {},
    wait: true
    forceUpdate: true
    success: (model, response) ->
      notify "success", "Updated Profile"
    error: (model, response) ->
      notify "error", "Couldn't Update"
person Sarah Tattersall    schedule 30.12.2012
comment
Я немного смущен. Я думал, что вы используете Backbone 0.9.1 или 0.9.2, так как метод isValid был удален в версии 0.9.9. Но теперь вы ссылаетесь на фрагмент кода в Backbone 0.9.9. Насколько я могу судить, метод clear не вызывался в методе save до версии 0.9.9. На самом деле метод clear был даже удален в последней версии 0.9.9(raw.github.com /documentcloud/backbone/master/backbone.js). Что еще хуже, метод isValid возродился в этой последней версии. Так какую версию вы на самом деле используете? - person Hui Zheng; 31.12.2012
comment
0.9.9, а то я уже запутался. В документации говорится об очистке, и действительно журнал изменений (на backbonejs.org/) действительно действительно говорит, что isValid был удалено, но, как вы указали, последняя версия по-прежнему содержит isValid. - person Sarah Tattersall; 02.01.2013
comment
В качестве быстрого обновления я понял, что мой isValid исходит из проверки магистрали (github.com/thedersen/backbone .validation), а не сама магистраль - person Sarah Tattersall; 02.01.2013

Вы уверены, что атрибуты модели были установлены правильно до save? Даже если ни один из его атрибутов не установлен, он все равно может пройти validate (в зависимости от того, как определена функция validate). Пожалуйста, попробуйте распечатать модель в консоли, чтобы убедиться в этом. Кстати, лучше передать null вместо {} в save, тогда метод set модели не будет вызываться.

Обновлено:

Согласно исходному коду Backbone, при передаче null в качестве первого аргумента save атрибуты модели будут сохранены до тех пор, пока модель не будет успешно сохранена на сервере. Таким образом, другая возможность заключается в том, что ваш сервер успешно сохранил модель, но вернул поврежденный объект, что привело к сбою в методе модели set. Если вы все еще не можете решить проблему, может помочь отслеживание метода model.set

person Hui Zheng    schedule 30.12.2012
comment
Я уже добавлял журнал модели в свой вопрос, чтобы вы могли его увидеть. Также изменение {} на null, похоже, не помогло, но я изменю его в своем режиме для лучшей практики. - person Sarah Tattersall; 30.12.2012
comment
@SarahTattersall Я только что обновил свой ответ, проверьте, помогает ли это. - person Hui Zheng; 30.12.2012
comment
Это запрос PUT, поэтому я отвечаю head :no_content в моем контроллере Rails. Вместо этого я пробовал answer_with @student, но это тоже не помогает? Я также немного сомневаюсь в том, чтобы отвечать студенту, когда это запрос PUT? - person Sarah Tattersall; 30.12.2012
comment
@SarahTattersall Если вы передали null или {} в save, сервер должен ответить объекту со всеми обновленными атрибутами. После этого Backbone вызовет model.parse(response, xhr) (по умолчанию просто возвращает переданный ответ) и использует возвращенное значение для установки атрибутов модели. Ваша проблема может быть исправлена, если сервер вернет соответствующий объект JSON. Кстати, вполне разумно ответить студенческому объекту в запросе PUT. - person Hui Zheng; 30.12.2012
comment
@SarahTattersall Если вы все еще не можете решить проблему, может помочь отслеживание метода model.set. - person Hui Zheng; 30.12.2012
comment
Даже ответ с помощью JSON-версии студента, похоже, не исправит ситуацию. Я изучу набор, если это возможно - person Sarah Tattersall; 30.12.2012