🦋

Serverpod 〜UserIDを使って検索する

2023/11/04に公開

自分が作ったデータだけを表示する

前回、自分のIdを、自分で作成したデータに紐付けて登録した。
今回は、そのデータを、自分のPageに表示する。
私が作っているのは、「BigBangから今までのすべて」を対象とした
誇大妄想的年表Databaseだけれど、
この機能によって、
「次の定期試験の範囲の年表を登録して覚えるのに使おう」
などというミニマムな需要にも対応できる、はず。

endpointに関数を書く

自分のIDという単一のkeywordを使って、
紐付けられている複数のDataからなるListを取得する。

中間tableの関数

import 'package:serverpod/serverpod.dart';
import 'package:acorn_server/src/generated/protocol.dart';

class PrincipalUserEndpoint extends Endpoint {
  //userIDを使って、主dataのIdをとる。
  Future<List<PrincipalUser>> getPUserId(Session session, {int? userId}) async {
    return await PrincipalUser.find(
      session,
      orderBy: PrincipalUser.t.principal_id,
    );
  }

  //userIDと主dataを紐付けて記録する。
  Future<int> addPrincipalUser(Session session, PrincipalUser pUser) async {
    await PrincipalUser.insert(session, pUser);
    return pUser.id!;
  }
}

二段階検索

ちなみに、中間tableを使った検索は、今は手作業で二つの関数を繋いでいるけれど、
間もなくServerpod1.2が出て、そこではJoin関数が実装されるそうです。

Future<List<Principal>> getPrincipalByUserId(Session session, {int? userId}) async {
  print("Getting principal with userId: $userId");

  if (userId == null) {
    return Future.value([]); // Return empty list if no userId is provided
  }

  // Step 1: Get principalIds from PrincipalUser using userId
  var whereClausePrincipalUser = PrincipalUser.t.user_id.equals(userId);
  
  var PrincipalUserResults = await PrincipalUser.find(session, where: (_) => whereClausePrincipalUser);
  var principalIds = PrincipalUserResults.map((row) => row.principal_id).toList();

  if (principalIds.isEmpty) {
    return Future.value([]);
  }

  // Step 2: Get Principals using principalIds
  var whereClausePrincipal;
  for (var principalId in principalIds) {
    if (whereClausePrincipal == null) {
      whereClausePrincipal = Principal.t.id.equals(principalId); // Assuming the id field in Principal table is named 'id'
    } else {
      whereClausePrincipal = whereClausePrincipal | Principal.t.id.equals(principalId);
    }
  }

  return await Principal.find(
    session,
    where: (_) => whereClausePrincipal,
    orderBy: Principal.t.point,

Flutter側を作る

View

import 'package:acorn_client/acorn_client.dart';
import 'package:acorn_flutter/users/account_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:serverpod_auth_shared_flutter/serverpod_auth_shared_flutter.dart';
import 'package:acorn_flutter/serverpod_client.dart';
import '../index.dart';
import 'sign_in_page.dart';

class AccountPage extends StatelessWidget {
  const AccountPage({ super.key });

  
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => AccountModel(),
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Account Page'),
        ),
        floatingActionButton: FloatingActionButton.extended(
          label: const Text('Moving On'),
          onPressed: () {
            Navigator.push<String>(
              context,
              MaterialPageRoute(
                builder: (context) => sessionManager.isSignedIn
                    ? const IndexPage()
                    : const SignInPage(),
              ),
            );
          },
        ),
        body: Consumer<AccountModel>(
          builder: (context, model, child) {
          return Container(
            decoration: const BoxDecoration(
              image: DecorationImage(
                  image: AssetImage('assets/images/both.png'), fit: BoxFit.cover),
            ),
            child: Column(
              children: [
                Expanded(
                  flex: 1,
                  child: Row(children: [
                    Expanded(
                        flex: 3,
                        child: ListView(children: [
                          ListTile(
                            contentPadding:
                                const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
                            leading: CircularUserImage(
                              userInfo: sessionManager.signedInUser,
                              size: 42,
                            ),
                            title: Text(sessionManager.signedInUser!.userName,
                                style:
                                    const TextStyle(color: Colors.white, fontSize: 20)),
                            subtitle: Text(sessionManager.signedInUser!.email ?? '',
                                style:
                                    const TextStyle(color: Colors.white, fontSize: 20)),
                          )
                        ])),
                    Expanded(
                      flex: 1,
                      child: Padding(
                        padding: const EdgeInsets.all(8),
                        child: ElevatedButton(
                          onPressed: () {
                            var userId = sessionManager.signedInUser?.id ?? 0;
                            model.fetchPrincipalByUserId(userId: userId);
                          },
                          child: const Text('My Events'),
                        ),
                      ),
                    ),
                    Expanded(
                      flex: 1,
                      child: Padding(
                        padding: const EdgeInsets.all(8),
                        child: ElevatedButton(
                          onPressed: () {
                            sessionManager.signOut();
                            Navigator.push<String>(
                              context,
                              MaterialPageRoute(
                                builder: (context) => const SignInPage(),
                              ),
                            );
                          },
                          child: const Text('Sign out'),
                        ),
                      ),
                    ),
                  ]),
                ),
                Expanded(
                  flex: 6,
                  child: ListView.builder(
                    itemCount: model.principal.length ?? 0,
                    itemBuilder: (context, index) {
                      return Padding(
                        padding: const EdgeInsets.fromLTRB(30, 10, 30, 10),
                        child: Card(
                          color: const Color(0xFFe6e6fa),
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: ListTile(
                              leading: Text(model.principal[index].annee ,
                                style: const TextStyle(fontSize: 16),
                              ),
                              title: Text(model.principal[index].affair,
                                style: const TextStyle(fontSize: 24),
                              ),
      ***

Model

import 'dart:core';

import 'package:flutter/material.dart';
import 'package:acorn_client/acorn_client.dart';
import 'package:serverpod_flutter/serverpod_flutter.dart';

var client = Client('http://localhost:8080/')
  ..connectivityMonitor = FlutterConnectivityMonitor();

class AccountModel extends ChangeNotifier {

  List<Principal> principal = [];

  fetchPrincipalByUserId({int? userId}) async {
    try {
      principal = await client.principal.getPrincipalByUserId(userId: userId);
      print("Getting principal with keywords: $userId");
      notifyListeners();
    } on Exception catch (e) {
      debugPrint('$e');
    }
  }
}

こんな感じ

日々の歩みを支えてくれるのは

https://flutteruniv.com/?invite_id=9hsdZHg0qtaMIr6RPRulAaRJfA83

Flutter大学

Discussion