Eloquent
Introducation
Vania includes Eloquent, an object-relational mapper (ORM) that makes it enjoyable to interact with your database. When using Eloquent, each database table has a corresponding "Model" that is used to interact with that table. In addition to retrieving records from the database table, Eloquent models allow you to insert, update, and delete records from the table as well.
Generating Model Classes
To get started, let's create an Eloquent model. Models typically live in the app\models
directory and extend the Vania Model class. You may use the make:model Vania command to generate a new model:
vania make:model model_name
Eloquent Model Conventions
Models generated by the make:model command will be placed in the app/Models
directory. Let's examine a basic model class and discuss some of Eloquent's key conventions:
import 'package:vania/vania.dart';
class User extends Model {
}
Table Names
In the example above, you may have noticed that we didn't explicitly specify the database table corresponding to our User model. By default, when you create the model using the Vania CLI, it will prompt you to enter the table name. However, if you wish to customize the table name further, you can use the super keyword to override it:
import 'package:vania/vania.dart';
class User extends Model {
User() {
super.table('users');
}
}
// Model with the new table name
class User extends Model {
User() {
super.table('user_tables');
}
}
By following these conventions, you can effortlessly define and interact with database tables using Eloquent within your Vania application.
Retrieving Results
Retrieving All Rows From A Table
To begin a fluent query, use the query method on the Vania model. The query method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally get the results. In this example, let's just get all records from a table:
import 'package:blog/app/models/user.dart';
import 'package:vania/vania.dart';
class HomeController extends Controller {
Future<Response> index(Request request) async {
final users = await User().query().get();
return Response.json(
{
'message': 'Hi ${users[0]['first_name']} ${users[0]['last_name']}',
}
);
}
}
Retrieving A Single Row / Column From A Table
If you just need to retrieve a single row from the database table, you may use the first method. This method will return a single Map
import 'package:blog/app/models/user.dart';
import 'package:vania/vania.dart';
class HomeController extends Controller {
Future<Response> index(Request request) async {
final user = await User().query().where('id','=',1).first();
return Response.json(
{
'message': 'Hi ${user['first_name']} ${user['last_name']}',
}
);
}
}
Retrieving exists
Determine if any rows exist for the current query.
final user = await User().query().where('id','=',1).exists();
Retrieving A List Of Column Values
If you would like to retrieve an array containing the values of a single column, you may use the pluck method. In this example, we'll retrieve an array of role titles:
final users = await User().query()->pluck('first_name')
for(String user in users){
print(user);
}
You may also specify a custom key column for the returned array:
final users = await User().query()->pluck('first_name','name')
Pagination And SimplePagination
paginate
The paginate
method is used to fetch a paginated set of data. It allows you to specify the number of items per page and the page number. This method returns a detailed pagination object which includes metadata such as total items, total pages, current page, and the data items.
Syntax
Future<PaginatedResult> paginate([int perPage = 15, int page = 1])
- perPage (optional): The number of items to be displayed per page. Defaults to 15.
- page (optional): The page number to retrieve. Defaults to 1.
Example Usage
final user = await User().query().paginate();
final user2 = await User().query().where('name','like','%Vania%').paginate(10, 2);
simplePagination
The simplePagination
method is used to fetch a paginated set of data in a simplified format. It also allows you to specify the number of items per page and the page number. This method returns a simpler pagination object which includes only the data items and basic pagination information.
SimplePagination Syntax
Future<SimplePaginatedResult> simplePagination([int perPage = 15, int page = 1])
- perPage (optional): The number of items to be displayed per page. Defaults to 15.
- page (optional): The page number to retrieve. Defaults to 1.
Example Usage simplePagination
final user = await User().query().where('name','like','%Vania%').simplePagination();
final user2 = await User().query().simplePagination(10, 2);
Selects
Specifying A Select Clause
Of course, you may not always want to select all columns from a database table. Using the select
method, you can specify a custom select
clause for the query
final users = await User().query().select(['first_name','last_name','email']).get();
The distinct
method allows you to force the query to return distinct results:
final users = await User().query().distinct().get();
Raw Expressions
Sometimes you may need to use a raw expression in a query. These expressions will be injected into the query as strings, so be careful not to create any SQL injection points! To create a raw expression
final users = await User().query().selectRaw('count(*) as user_count, status').get();
Joins
Inner Join Statement
To perform a basic SQL "inner join", you may use the join method on a query. The first argument passed to the join method is the name of the table you need to join to, while the remaining arguments specify the column constraints for the join. Of course, as you can see, you can join to multiple tables in a single query:
final user = await User().query()
.join('clientes_grupos','clientes_grupos.user_id','=','users.id')
.first();
Left Join Statement
If you would like to perform a "left join" instead of an "inner join", use the leftJoin method. The leftJoin method has the same signature as the join method:
final user = await User().query()
.leftJoin('clientes_grupos','clientes_grupos.user_id','=','users.id')
.first();