Skip to content

Commit

Permalink
feat: adds findOrCreateBy to schema (#1611)
Browse files Browse the repository at this point in the history
  • Loading branch information
samselikoff authored May 8, 2019
1 parent dba7607 commit 1159d39
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 4 deletions.
36 changes: 32 additions & 4 deletions addon/orm/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export default class Schema {
all: (attrs) => this.all(camelizedModelName, attrs),
find: (attrs) => this.find(camelizedModelName, attrs),
findBy: (attrs) => this.findBy(camelizedModelName, attrs),
findOrCreateBy: (attrs) => this.findOrCreateBy(camelizedModelName, attrs),
where: (attrs) => this.where(camelizedModelName, attrs),
none: (attrs) => this.none(camelizedModelName, attrs),
first: (attrs) => this.first(camelizedModelName, attrs)
Expand Down Expand Up @@ -246,7 +247,7 @@ export default class Schema {
}

/**
Returns the first model in the database that matches the key-value pairs in the `query` object. Note that a string comparison is used.
Returns the first model in the database that matches the key-value pairs in `attrs`. Note that a string comparison is used.
```js
let post = blogPosts.findBy({ published: true });
Expand All @@ -261,9 +262,36 @@ export default class Schema {
*/
findBy(type, query) {
let collection = this._collectionForType(type);
let records = collection.findBy(query);
let record = collection.findBy(query);

return this._hydrate(records, dasherize(type));
return this._hydrate(record, dasherize(type));
}

/**
Returns the first model in the database that matches the key-value pairs in `attrs`, or creates a record with the attributes if one is not found.
```js
// Find the first published blog post, or create a new one.
let post = blogPosts.findBy({ published: true });
```
@method findOrCreateBy
@param type
@param attributeName
@public
*/
findOrCreateBy(type, attrs) {
let collection = this._collectionForType(type);
let record = collection.findBy(attrs);
let model;

if (!record) {
model = this.create(type, attrs);
} else {
model = this._hydrate(record, dasherize(type));
}

return model;
}

/**
Expand Down Expand Up @@ -300,7 +328,7 @@ export default class Schema {
*/
first(type) {
let collection = this._collectionForType(type);
let [record] = collection;
let record = collection[0];

return this._hydrate(record, dasherize(type));
}
Expand Down
55 changes: 55 additions & 0 deletions tests/integration/orm/find-or-create-by-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Schema from 'ember-cli-mirage/orm/schema';
import Model from 'ember-cli-mirage/orm/model';
import Db from 'ember-cli-mirage/db';
import {module, test} from 'qunit';

module('Integration | ORM | #findOrCreateBy', function(hooks) {
hooks.beforeEach(function() {
let db = new Db({ users: [
{ id: 1, name: 'Link', good: true },
{ id: 2, name: 'Zelda', good: true },
{ id: 3, name: 'Ganon', good: false }
] });

this.User = Model.extend();

this.schema = new Schema(db, {
user: this.User
});
});

test('it returns the first model that matches the attrs', function(assert) {
let user = this.schema.users.findOrCreateBy({ good: true });

assert.ok(user instanceof this.User);
assert.deepEqual(user.attrs, { id: '1', name: 'Link', good: true });
});

test('it creates a model if no existing model with the attrs is found', function(assert) {
assert.equal(this.schema.db.users.length, 3);

let newUser = this.schema.users.findOrCreateBy({ name: 'Link', good: false });

assert.equal(this.schema.db.users.length, 4);
assert.ok(newUser instanceof this.User);
assert.deepEqual(newUser.attrs, { id: '4', name: 'Link', good: false });
});

// test('it returns models that match using a query function', function(assert) {
// let users = schema.users.where(function(rec) {
// return !rec.good;
// });
//
// assert.ok(users instanceof Collection, 'it returns a collection');
// assert.equal(users.models.length, 1);
// assert.ok(users.models[0] instanceof User);
// assert.deepEqual(users.models[0].attrs, { id: '3', name: 'Ganon', good: false });
// });

// test('it returns an empty collection if no models match a query', function(assert) {
// let users = schema.users.where({ name: 'Link', good: false });
//
// assert.ok(users instanceof Collection, 'it returns a collection');
// assert.equal(users.models.length, 0);
// });
});

0 comments on commit 1159d39

Please sign in to comment.