16

I've kinda been struggling with this for some time; let's see if somebody can help me out.

Although it's not explicitly said in the Readme, ember-data provides somewhat validations support. You can see that on some parts of the code and documentation:

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/model/states.js#L411

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/model/states.js#L529

The REST adapter doesn't add validations support on itself, but I found out that if I add something like this in the ajax calls, I can put the model on a "invalid" state with the errors object that came from the server side:

error: function(xhr){
  var data = Ember.$.parseJSON(xhr.responseText);
  store.recordWasInvalid(record, data.errors);
}

So I can easily to the following:

var transaction = App.store.transaction();
var record = transaction.createRecord(App.Post);
record.set('someProperty', 'invalid value');
transaction.commit()
// This makes the validation fail

record.set('someProperty', 'a valid value');
transaction.commit();
// This doesn't trigger the commit again.

The thing is: As you see, transactions don't try to recommit. This is explained here and here.

So the thing is: If I can't reuse a commit, how should I handle this? I kinda suspect that has something to do to the fact I'm asyncronously putting the model to the invalid state - by reading the documentation, it seems like is something meant for client-side validations. In this case, how should I use them?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
josepjaume
  • 419
  • 5
  • 15

6 Answers6

4

I have a pending pull request that should fix this

https://github.com/emberjs/data/pull/539

Cyril Fluck
  • 1,561
  • 7
  • 9
2

I tried Javier's answer, but I get "Invalid Path" when doing any record.set(...) with the record in invalid state. What I found worked was:

// with the record in invalid state
record.send('becameValid');
record.set('someProperty', 'a valid value');
App.store.commit();

Alternatively, it seems that if I call record.get(...) first then subsequent record.set(...) calls work. This is probably a bug. But the above work-around will work in general for being able to re-commit the same record even without changing any properties. (Of course, if the properties are still invalid it will just fail again.)

webjprgm
  • 4,331
  • 2
  • 18
  • 14
  • I've added `record.send('becameValid');` in my model `becomeInvalid` function. This worked around my problem. This is inspired by a comment on GitHub pull request from Cyril. – ybart Apr 11 '13 at 09:59
1

this may seem to be an overly simple answer, but why not create a new transaction and add the pre-existing record to it? i'm also trying to figure out an error handling approach.

also you should probably consider writing this at the store level rather than the adapter level for the sake of re-use.

Adam Krawesky
  • 1,313
  • 11
  • 23
1

For some unknown reason, the record becomes part of the store default transaction. This code works for me:

var transaction = App.store.transaction();
var record = transaction.createRecord(App.Post);
record.set('someProperty', 'invalid value');
transaction.commit()

record.set('someProperty', 'a valid value');
App.store.commit(); // The record is created in backend

The problem is that after the first failure, you must always use the App.store.commit() with the problems it has.

0

Give a look at this gist. Its the pattern that i use in my projects.

https://gist.github.com/danielgatis/5550982

danielgatis
  • 737
  • 7
  • 19
0

@josepjaume

Take a look at https://github.com/esbanarango/ember-model-validator.

Example:

import Model, { attr } from '@ember-data/model';
import { modelValidator } from 'ember-model-validator';

@modelValidator
export default class MyModel extends Model {
  @attr('string') fullName;
  @attr('string') fruit;
  @attr('string') favoriteColor;

  validations = {
    fullName: {
      presence: true
    },
    fruit: {
      presence: true
    },
    favoriteColor: {
      color: true
    }
  };
}
esbanarango
  • 1,634
  • 15
  • 17