`mongod` allows you to use structs as `models` with data. it is build upon a MongoDB database. You need to pass a Connection URI for the database to use via the `$DB_URI` environment variable. The database to use can be configured via `$DB` environment variable.
You can derive the `Model` and `Referencable` traits for your struct. This will provide you with functions like `insert()`, `delete()`, `update()`, `get()`, etc for your struct. Additionally you have to manually implement the `Validate` trait which ensures a consistent valid state of your struct in order to never insert invalid data into the database.
If you want certain fields to remember a history of changes you can use the `Historic<T>` type.
This type will retain previous changes along with a timestamp when updates happen.
### References
A Models field can be a reference to another model using the `Reference` type.
```rust
let m = MyStruct::get("someid").await.unwrap();
// get a reference from model
// `reference()` is a convenience function and is exactly the same as the two references below
let myref = m.reference();
let sec_ref = Reference::new(MyStruct::collection_name(), "someid").await.unwrap();
let third_ref = Reference::new("my_struct", "someid").await.unwrap();
struct OtherStruct {
link: Reference
}
// store a reference
let other = OtherStruct{
link: myref
}
let m: MyStruct = other.link.get().await; // get back a model from reference
```
With the `assert_reference_of!()` macro you can limit the models your reference can represent at validation. You can specify as many models as you want, but the reference must match one of them.
Sometimes you need only some fields of your `Model`. When deriving the `Model` trait you automatically get a `Partial` of your model. Partials are only meant for reading values so you cant call functions like `update()`, but you can still get a `Reference` to the original `Model`. This saves bandwidth and memory. You can access it like this:
```rust
// say you are only interested in the reference field `other` of `MyStruct`
let ms = MyStruct::get_partial("someid", &serde_json::json!({"other": 1})).await.unwrap();