🦋
Serverpod ~ForeignKeyはNullableという発見
fieldにNullがあってはいけない、と聞いたので
必死にtable構成を考えて、中間tableを作って、
そしたらSeverpodがJOIN未実装と言われて・・・という話は前にも書いた。
しっかり勉強してから実行、という性格ではないので、ときどきひどく遠回りをする。
今回など、その典型だろう。
中間tableをつくりまくりながら、
いくらコンピューターの仕事が早いといっても、なんか変だな、と思っていた。
イベント会場でこんな動線を引いたら、絶対混乱する。
で、新しいtutorial動画を見ていたら、あれnullableのfield作ってる!?
しかも、Listをいれたfieldまである!
で、改めて調べたら、ForeignKeyはNullableって、
JOINは重いですからねえって、
Serverpodの独自機能ってわけじゃない、SQLの常識だったらしい。
早く言ってよ〜(基礎勉強しろ!)
Listの対応についてはまだよくわからないのだが、
少なくとも一対一対応で、
Null対策のためだけにつくった中間tableは撤廃した。
これでendpointを書けば、外部キーでの絞り込みがOneStepでできる。
Chipで選んだキーワードのIdをListにして絞り込み
こんなふうにprotocolに外部キーを入れて
class: Principal
table: principal
fields:
annee: int
affair: String
pays: String
placeId: int?, parent=places
cattId: int?, parent=countryatts
pattId: int?, parent=placeatts
こんな関数をendpointに書いて
Future<List<Principal>> getPrincipalByCatt(Session session, {List<int>? keynumbers}) async {
print("Getting principal with cattIds: $keynumbers");
var whereClause;
if (keynumbers != null && keynumbers.isNotEmpty) {
for (var keynumber in keynumbers) {
if (whereClause == null) {
whereClause = Principal.t.cattId.equals(keynumber);
} else {
whereClause = whereClause | Principal.t.cattId.equals(keynumber);
}
}
} else {
whereClause = Constant(true);
}
return await Principal.find(
session,
where: (_) => whereClause,
orderBy: Principal.t.annee,
);
}
Flutter側はこんな感じ
import 'package:flutter/material.dart';
import 'package:acorn_client/acorn_client.dart';
import 'package:serverpod_flutter/serverpod_flutter.dart';
class SearchByOptionsModel extends ChangeNotifier {
var client = Client('http://localhost:8080/')
..connectivityMonitor = FlutterConnectivityMonitor();
List<Principal> _principal = [];
List<Principal> get principal => _principal;
List<Principal> get principalByPlaces => _principal;
fetchPrincipal({List<String>? countries}) async {
try {
_principal = await client.principal.getPrincipal(keywords: countries);
print("Getting principal with keywords: $countries");
notifyListeners();
} on Exception catch (e) {
debugPrint('$e');
}
}
fetchPrincipalByPlaces({List<int>? listPlaceIds}) async {
try {
_principal = await client.principal.getPrincipalByPlaces(keynumbers: listPlaceIds);
print("Getting principal with keynumbers: $listPlaceIds");
notifyListeners();
} on Exception catch (e) {
debugPrint('$e');
}
}
}
もっとシンプルにできそう
Serverpodのtable構成変更はそんなに難しくないが(自動生成でどんどん変わっていくから)
PostgreSQL側は手作業で「そこは直せません」とか言われるので、
真面目な方は、よく考えてから作り始めましょう\(^O^)/
Discussion