clinical:base-model

v1.5.0Published 4 years ago

This package has not had recent updates. Please investigate it's current state before committing to using it in your project.

Base Model

Provides an extensible base from which other extensible models can be built.

How it works

BaseModel is the foundation on which the Socialize package set is built. It provides an easy way to set up your models with helpers and other convenience functions. Once you have created your models its as simple running find and findOne queries on your collections to get instances of the model. Once you have an instance you can then use the helpers to display data or the helper methods to modify and update the data for the model.

Usage

Assuming we need to model books, we create the model like so.

1Book = BaseModel.extendAndSetupCollection("books");

This creates a Class named Book, collection named books, assigns a reference for the collection to Meteor.books and tells the collection to return instances of the model instead of regular documents.

Now for security we need to set up the schema for the collection. BaseModel provides a convenient static method for adding a SimpleSchema to the collection, which is inherited by our classes when we extend BaseModel.

1Book.appendSchema({
2  "userId":{
3    type: String,
4    regEx: SimpleSchema.RegEx.Id,
5    autoValue: function() {
6      if(this.isInsert){
7        return this.userId;
8      }
9    }
10  },
11  "title":{
12    type: String
13    max: 30,
14  },
15  "subTitle":{
16    type: String,
17    max: 100
18  },
19  "authorId":{
20    type: String,
21    regEx: SimpleSchema.RegEx.Id
22  }
23});

And to finalize the write security we will use some light checking in allow or deny

1Meteor.books.allow({
2  insert: function(userId, book){
3    //book is an instance of Book class thanks to collection transforms.
4    return book.checkOwnership() && !!Meteor.authors.findOne(this.authorId);
5  },
6  update: function(userId, book){
7    //book is an instance of Book class thanks to collection transforms.
8    return book.checkOwnership();
9  },
10  remove: function(userId, book) {
11    //book is an instance of Book class thanks to collection transforms.
12    return book.checkOwnership()
13  }
14});

Now that we have a Book class with a SimpleSchema attached to it's collection and allow rules in place, we can give it some helper methods that let us access it's data and reference related models.

1Book.methods({
2  "owner": function(){
3    return Meteor.users.findOne(this.userId);
4  },
5  "author": function() {
6    //return an instance of Author that itself has methods
7    return Meteor.authors.findOne(this.authorId);
8  },
9  "fullTitle": function() {
10    return this.title + ": " + this.subTitle;
11  }
12});

Now we are all set up to use the new Book class, and since we've properly secured our database writes through a cobination of SimpleSchema and allow rules, we can now do all of our database operations using client side database methods.

Lets Insert a book

1var author = Meteor.authors.findOne({firstName:"Florence", lastName:"Nightingale"});
2
3var book = new Book({
4  title: "Notes on Nursing",
5  subTitle: "What It Is, and What It Is Not",
6  authorId: author._id
7});
8
9book.save();

Now, assuming we have a template with a helper that returns a cursor from Meteor.books, we can now use the methods of the Book class as template helpers as well.

1<h1>Book List</h1>
2{{#each books}}
3  <p>{{author.fullName}}<p>
4  <p>{{fullTitle}}</p>
5{{/each}}

BaseModel (class)

Instance Methods

Instance methods are helper functions available on the instances returned from find and findOne queries. BaseModel provides some that are inherited in the extend process.

checkOwnership - Check to make sure the userId property is equal to the _id of the currently logged in user.

1var myBook = Meteor.books.findOne();
2if(myBook.checkOwnership()){
3  mybook.remove();
4}

set - update a property of the underlying data. This also updates the underlying minimongo collection if a record exists, and will reflect the change on the page if displayed there. This however does not save the data to the server side database. To save to server call the save method on the instance.

If using this in a reactive context such as the data context of a template and modifying in an event attached to that template, you will need to save a copy to the template and modify that as modifying the underlying minimongo will cause a recomputation and wipe out any changes to the instance that was the data context

1var book = Meteor.books.findOne();
2
3book.set("title", "Gray's Anatomy");

save - Save instance to the database. If the instance was not previously saved to the database this will perform an insert. Otherwise it will diff the changes and update the database using a $set and update.

1var book = Meteor.books.findOne();
2
3book.set("title", "Hippocratic Writings");
4
5book.save();

update(modifier) - Update the record for the instance making changes specified by the modifier. In most cases it'll be easier to use save but this is here if needed.

1Meteor.books.findOne().update({$set:{title:"Germ Theory and Its Applications to Medicine"}});

remove - Delete the database record for the instance.

1Meteor.books.findOne().remove();

Static Methods

extendAndSetupCollection("collectionName") - Extend BaseModel and then set up the collection for the model and assign it to Meteor[collectionName] for ease of access outside of file and package scope.

1Author = BaseModel.extendAndSetupCollection("authors");

appendSchema(SchemaObject) - Create attach a schema or add to the schema if one already exists. SchemaObject is the same as you would pass to new SimpleSchema(SchemaObject).

1Author.attachSchema({
2	"firstName":{
3		type: String,
4		max: 20
5	},
6	"lastName": {
7		type: String,
8		max: 20
9	}
10});

methods(methodObject) - add methods to the class. methodsObject is a hash of functions.

1Author.methods({
2	fullName: function() {
3		return this.firstName +" "+ this.lastName;
4	}
5});

createEmpty(id) - Returns an instance with only the _id field set as the specified id {_id:"8D7XmQb3KEpGqc3AD"}. Handy for when you already have the _id of a record and want to do an update to the collection but don't want to do a full database call to get a populated instance.