Merge branch 'master' of github.com:qutheory/documentation

This commit is contained in:
Tanner Nelson 2016-09-09 02:33:26 -04:00
commit fc67a8f81b
No known key found for this signature in database
GPG Key ID: 9C24375C64856B76
9 changed files with 35 additions and 32 deletions

View File

@ -20,7 +20,7 @@ Not all drivers have providers yet, and not all drivers or providers are up to d
## Creating a Driver
Fluent is a power, database agnostic package for persisting your models. It was designed from the beginnign to work with both SQL and NoSQL databases alike.
Fluent is a powerful, database agnostic package for persisting your models. It was designed from the beginning to work with both SQL and NoSQL databases alike.
Any database that conforms to `Fluent.Driver` will be able to power the models in Fluent and Vapor.
@ -29,7 +29,7 @@ The protocol itself is fairly simple:
```swift
public protocol Driver {
var idKey: String { get }
func query<T: Entity>(_ query: Query<T>) throws -> Node
func query<T: Entity>(_ query: Query<T>) throws -> Node
func schema(_ schema: Schema) throws
func raw(_ raw: String, _ values: [Node]) throws -> Node
}

View File

@ -211,6 +211,10 @@ public protocol Model: Entity, JSONRepresentable, StringInitializable, ResponseR
As can be seen in the protocol, Vapor models can automatically convert to `JSON`, `Response`, and even be used in type-safe routing.
## Options
Change the table/collection name
```swift
static var entity = "new_name"
```

View File

@ -4,7 +4,7 @@ currentMenu: fluent-query
# Query
The `Query` class is what powers every interaction with Fluent. Whether you're fetching a model with `.find()` or saving to the database, there is a `Query` involved somewhere.
The `Query` class is what powers every interaction with Fluent. Whether you're fetching a model with `.find()` or saving to the database, there is a `Query` involved somewhere.
## Querying Models
@ -14,7 +14,7 @@ Every type that conforms to [Model](model.md) gets a static `.query()` method.
let query = try User.query()
```
This is how you can create a `Query<User>`.
This is how you can create a `Query<User>`.
### No Database
@ -24,11 +24,11 @@ The `.query()` method is marked with `try` because it can throw an error if the
User.database = drop.database
```
This property is set automatically when you pass the Model as a preparation.
This property is set automatically when you pass the Model as a preparation.
## Filter
The most common types of queries involve filtering data.
The most common types of queries involve filtering data.
```swift
let smithsQuery = try User.query().filter("last_name", "Smith")
@ -61,7 +61,7 @@ Partially matching filters can also be applied.
let statesWithNew = try State.query().filter("name", contains: "New")
```
## Retrieving
## Retrieving
There are two methods for running a query.
@ -75,7 +75,7 @@ let usersOver21 = try User.query().filter("age", .greaterThanOrEquals, 21).all()
### First
The first matching entity can be fetch. This returns an optional `Model?`, in this case a user.
The first matching entity can be fetched. This returns an optional `Model?`, in this case a user.
```swift
let firstSmith = try User.query().filter("last_name", "Smith").first()
@ -111,7 +111,7 @@ Custom foreign keys can be provided through overloads to `union`.
## Raw Queries
Since Fluent is focused on interacting with models, each Query requires a model type. If you want to do raw database queries that aren't based on a model, you should use the underlying Fluent Driver to do so.
Since Fluent is focused on interacting with models, each Query requires a model type. If you want to do raw database queries that aren't based on a model, you should use the underlying Fluent Driver to do so.
```swift
if let mysql = drop.database?.driver as? MySQLDriver {

View File

@ -36,7 +36,7 @@ let owner = try pet.parent(pet.ownerId, Owner.self).get()
The parent method requires the foreign key for the parent as well as the type.
### Convenience
### Convenience
To make requesting a parent easier, a method can be added to the model.
@ -50,7 +50,7 @@ extension Pet {
Since we are extending `Pet`, we no longer need to use `pet.` before the `ownerId`. Furthermore, because we are providing the type information about `Owner` in the return type of the method, we no longer need to pass that as an argument.
The `Parent<T>` type is a queryable object, meaning you could `delete()` the parent, `filter()`, etc.
The `Parent<T>` type is a queryable object, meaning you could `delete()` the parent, `filter()`, etc.
```swift
try pet.owner().delete()
@ -64,7 +64,7 @@ let owner = try pet.owner().get()
## Children
`Children` are the opposite side of the `Parent` relationship. Assuming the schema from the previous example, the pets could be retreived from an owner like so:
`Children` are the opposite side of the `Parent` relationship. Assuming the schema from the previous example, the pets could be retrieved from an owner like so:
```swift
let owner: Owner = ...
@ -95,7 +95,7 @@ let coolPets = try owner.pets().filter("type", .in, ["Dog", "Ferret"]).all()
## Siblings
`Sibilings` work differently from `Children` or `Parent` since they require a `Pivot`.
`Siblings` work differently from `Children` or `Parent` since they require a `Pivot`.
For an example, let's say we want to allow our pets to have multiple toys. But we also want the toys to be shared by multiple pets. We need a pivot entity for this.
@ -139,7 +139,7 @@ extension Toy {
}
```
Now you are free to query pets and toys simiarly to children.
Now you are free to query pets and toys similarly to children.
```swift
let pet: Pet = ...

View File

@ -59,7 +59,7 @@ The response is returned and will chain back up any remaining middleware and bac
## Request
The middleware can also modify or intereact with the request.
The middleware can also modify or interact with the request.
```swift
func respond(to request: Request, chainingTo next: Responder) throws -> Response {
@ -98,7 +98,7 @@ app.get("foo") { request in
}
```
This solution works, but it would get repetative if repeated throughout multiple routes. It can also easily lead to code duplication. Luckily, this error could be caught in a middleware instead.
This solution works, but it would get repetitive if repeated throughout multiple routes. It can also easily lead to code duplication. Luckily, this error could be caught in a middleware instead.
```swift
final class FooErrorMiddleware: Middleware {
@ -146,7 +146,7 @@ final class PokemonMiddleware: Middleware {
func respond(to request: Request, chainingTo next: Responder) throws -> Response {
let response = try next.respond(to: request)
if let pokemon = response.pokemon {
request.accept.prefers("html") {
response.view = try drop.view("pokemon.mustache", context: pokemon)
@ -210,4 +210,3 @@ drop.get("pokemon", Pokemon.self) { request, pokemon in
Middleware is incredibly powerful. Combined with extensions, it allows you to add functionality that feels native to the framework.
For those that are curious, this is how Vapor manages JSON internally. Whenever you return JSON in a closure, it sets the `json: JSON?` property on `Response`. The `JSONMiddleware` then detects this property and serializes the JSON into the body of the response.

View File

@ -97,7 +97,7 @@ extension VPRFile: HTTP.BodyRepresentable {
}
```
> You may have noticed above, that the protocol throws, but our implementation does not. This is compeletely valid in Swift and will allow you to not throw if you're ever calling the function manually.
> You may have noticed above, that the protocol throws, but our implementation does not. This is completely valid in Swift and will allow you to not throw if you're ever calling the function manually.
Now we're able to include our `VPR` file directly in our `Responses`.

View File

@ -76,4 +76,4 @@ This can be used as a jumping off point for applications looking to implement fe
## Client
The `HTTP.Client` is itself a `Responder` although, instead of handling the `Request` itsself, it passes it on to the underlying uri.
The `HTTP.Client` is itself a `Responder` although, instead of handling the `Request` itself, it passes it on to the underlying uri.

View File

@ -13,7 +13,7 @@ Vapor has a plethora of functionality for routing including route builders, grou
The most basic route includes a method, path, and closure.
```swift
drop.get("welcome") { request in
drop.get("welcome") { request in
return "Hello"
}
```
@ -21,7 +21,7 @@ drop.get("welcome") { request in
The standard HTTP methods are available including `get`, `post`, `put`, `patch`, `delete`, and `options`.
```swift
drop.post("form") { request in
drop.post("form") { request in
return "Submitted with a POST request"
}
```
@ -42,7 +42,7 @@ You can also use `/`, but commas are often easier to type and work better with t
## Alternate
An alternate syntax that accepts a `Method` as the first parameter is also available.
An alternate syntax that accepts a `Method` as the first parameter is also available.
```swift
drop.add(.trace, "welcome") { request in
@ -54,7 +54,7 @@ This may be useful if you want to register routes dynamically or use a less comm
## Request
Each route closure is given a single [Request](../http/request.md). This contains all of the data associated with the request that led to your route closure being called.
Each route closure is given a single [Request](../http/request.md). This contains all of the data associated with the request that led to your route closure being called.
## Response Representable
@ -132,7 +132,7 @@ If you want to override this behavior, remove the `AbortMiddleware` from the `Dr
Fallback routes allow you to match multiple layers of nesting slashes.
```swift
app.get("anything", "*") { request in
app.get("anything", "*") { request in
return "Matches anything after /anything"
}
```

View File

@ -8,7 +8,7 @@ Traditional web frameworks leave room for error in routing by using strings for
## Type Safe
To create a type safe route simply replace one of the parts of your path with a `Type`.
To create a type safe route simply replace one of the parts of your path with a `Type`.
```swift
drop.get("users", Int.self) { request, userId in
@ -19,7 +19,7 @@ drop.get("users", Int.self) { request, userId in
This creates a route that matches `users/:id` where the `:id` is an `Int`. Here's what it would look like using manual route parameters.
```swift
drop.get("users", ":id") { request in
drop.get("users", ":id") { request in
guard let userId = request.parameters["id"].int else {
throw Abort.badRequest
}
@ -28,7 +28,7 @@ drop.get("users", ":id") { request in
}
```
Here you can see that type safe routing saves ~3 lines of code and also prevents runtime errors like mispelling `:id`.
Here you can see that type safe routing saves ~3 lines of code and also prevents runtime errors like misspelling `:id`.
## String Initializable
@ -38,7 +38,7 @@ Any type that conforms to `StringInitializable` can be used as a type-safe routi
- Int
- Model
`String` is the most generic and always matches. `Int` only matches when the string supplied can be turned into an integer. `Model` only matches when the string, used as an identifier, can be used to find the model in the database.
`String` is the most generic and always matches. `Int` only matches when the string supplied can be turned into an integer. `Model` only matches when the string, used as an identifier, can be used to find the model in the database.
Our previous example with users can be further simplified.
@ -126,7 +126,7 @@ Manual request parameters also work with [groups](group.md).
```swift
let userGroup = drop.grouped("users", ":userId")
userGroup.get("messages") { req in
userGroup.get("messages") { req in
let user = try req.parameters.extract("userId") as User
}
```
```