Search code examples
flutter-moor

How To Create Flutter Moor Relationship With One-To-Many Join


I have a table Category which is Related to a Task table in a one-to-many relationship and I am attempting to perform a join using Moor.

I would like to return a list for the list of tasks that match a category. How do I do it?

      Stream<List<CategoryWithTask>> watchAllCategories() {
        return (select(categories)
              ..orderBy(([
                (c) => OrderingTerm(expression: c.name),
              ])))
            .join([leftOuterJoin(tasks, tasks.categoryId.equalsExp(categories.id))])
            .watch()
            .map((rows) => rows.map(
                  (row) {
                    return CategoryWithTask(
                        category: row.readTable(categories),
                        task: row.readTable(tasks)); // How do I modify this line to return a list of tasks corresponding to a category?
                  },
                ).toList());
      }

Solution

  • I managed to find a way with the support of the guys at Flutter Moor after creating an issue on Github. Below is the working code;

      Stream<List<CategoryWithTasks>> watchAllCategories() {
        return (select(categories)
              ..orderBy(([
                (c) => OrderingTerm(expression: c.name),
              ])))
            .join([leftOuterJoin(tasks, tasks.categoryId.equalsExp(categories.id))])
            .watch()
            .map((rows) {
              final groupedData = <Category, List<Task>>{};
    
              for (final row in rows) {
                final category = row.readTable(categories);
                final task = row.readTable(tasks);
    
                final list = groupedData.putIfAbsent(category, () => []);
                if (task != null) list.add(task);
              }
    
              return [
                for (final entry in groupedData.entries)
                  CategoryWithTasks(category: entry.key, tasks: entry.value)
              ];
            });
      }