Flint DartFlint Dart

πŸ—„ Models & ORM in Flint Dart

Flint Dart provides a simple Object-Relational Mapping (ORM)system that allows you to define models, map them to database tables, and interact with your data using Dart classes instead of writing raw SQL queries. This approach improves maintainability, reduces boilerplate, and makes your code more readable.

Defining a Model

To define a model in Flint Dart, extend the Model<T>class and implement:

  • Properties β€” Your model's fields.
  • toMap() β€” How the model is converted to a map.
  • fromMap() β€” How to create a model from a map.
  • table β€” The database table schema.
import 'package:flint_dart/model.dart';
import 'package:flint_dart/schema.dart';

class User extends Model<User> {
  String? id;
  String? name;
  String? email;
  String? password;
  String? profilePicUrl;

  @override
  Map<String, dynamic> toMap() => {
        'id': id,
        'name': name,
        'email': email,
      };

  @override
  User fromMap(Map<String, dynamic> map) => User()
    ..id = map['id']
    ..name = map['name']
    ..email = map['email']
    ..password = map["password"];

  @override
  Table get table => Table(
        name: 'users',
        columns: [
          Column(name: 'id', type: ColumnType.integer, isPrimaryKey: true, isAutoIncrement: true),
          Column(name: 'name', type: ColumnType.string, length: 255),
          Column(name: 'email', type: ColumnType.string, length: 255),
          Column(name: 'password', type: ColumnType.string),
          Column(name: 'created_at', type: ColumnType.datetime, isNullable: true),
        ],
      );
}

Common ORM Methods

Flint Dart ORM comes with built-in CRUD methods to make database interactions straightforward:

  • all() β€” Retrieve all records.
  • find(id) β€” Find a record by its primary key.
  • create(data) β€” Insert a new record.
  • update(id, data) β€” Update a record.
  • delete() β€” Remove a record.
final users = await User().all(); // Get all users
final user = await User().find(1); // Get user with ID 1
await User().create({'name': 'John', 'email': 'john@example.com'});
await User().update(1, {'name': 'Updated Name'});
await User().delete(1);

Example Controller Using Models

Here’s a controller using the User model and ORM methods for common CRUD operations. This example demonstrates listing, finding, updating, and deleting users.

import 'package:flint_dart/flint_dart.dart';
import 'package:flint_dart/storage.dart';
import 'package:sample/src/models/user_model.dart';

class UserController {
  Future<Response> index(Request req, Response res) async {
    final users = await User().all();
   return res.json({
      "message": 'List of user',
      "users": users.map((user) => user.toMap()).toList()
    });
  }

  Future<Response> show(Request req, Response res) async {
    var user = await User().find(req.params['id']);
    if (user != null) {
    return  return res.send('User ${user.toMap()}');
    }
  }

  Future<Response> create(Request req, Response res) async {
   return res.send('Creating user...');
  }

  Future<Response> update(Request req, Response res) async {
    try {
      final String userId = req.params['id']!;
      final body = await req.form();
      final String? name = body['name'];
      String? profilePicUrl;

      if (await req.hasFile('profile_pic')) {
        final file = await req.file('profile_pic');
        if (file != null) {
          final User? userToUpdate = await User().find(userId);
          if (userToUpdate != null || userToUpdate?.profilePicUrl != null) {
            profilePicUrl = await Storage.update(
                userToUpdate!.profilePicUrl!, file,
                subdirectory: 'profiles');
          } else {
            profilePicUrl =
                await Storage.create(file, subdirectory: 'profiles');
          }
        }
      }

      final User? userToUpdate = await User().find(userId);
      final Map<String, dynamic> updateData = {};
      if (name != null) updateData['name'] = name;
      if (profilePicUrl != null) updateData['profile_pic'] = profilePicUrl;

      if (updateData.isNotEmpty) {
        await userToUpdate!.update(userId, updateData);
      }

      final updatedUser = await User().find(userId);

     return res.json({
        "status": "success",
        "message": "User updated successfully.",
        "user": updatedUser?.toMap(),
      });
    } on ValidationException catch (e) {
     return res.status(422).json({"status": "errors", "errors": e.errors});
    } catch (e) {
     return res.status(500).json({
        "status": "error",
        "message": "Failed to update user: ${e.toString()}",
      });
    }
  }

  Future<Response?> delete(Request req, Response res) async {
   return res.send('Deleting user ${req.params['id']}');
  }
}