all orm tests pass
This commit is contained in:
parent
643661cf86
commit
d07ded57c4
10 changed files with 433 additions and 49 deletions
|
@ -108,12 +108,20 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
OrmBuildContext foreign;
|
||||
|
||||
if (foreignTable == null) {
|
||||
if (!isModelClass(field.type)) {
|
||||
if (!isModelClass(field.type) &&
|
||||
!(field.type is InterfaceType &&
|
||||
isListOfModelType(field.type as InterfaceType))) {
|
||||
throw new UnsupportedError(
|
||||
'Cannot apply relationship to field "${field.name}" - ${field.type.name} is not assignable to Model.');
|
||||
} else {
|
||||
try {
|
||||
var modelType = firstModelAncestor(field.type) ?? field.type;
|
||||
var refType = field.type;
|
||||
|
||||
if (refType is InterfaceType && isListOfModelType(refType)) {
|
||||
refType = (refType as InterfaceType).typeArguments[0];
|
||||
}
|
||||
|
||||
var modelType = firstModelAncestor(refType) ?? refType;
|
||||
|
||||
foreign = await buildOrmContext(
|
||||
modelType.element as ClassElement,
|
||||
|
@ -162,8 +170,14 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
if (isBelongsRelation(relation)) {
|
||||
var name = new ReCase(relation.localKey).camelCase;
|
||||
ctx.buildContext.aliases[name] = relation.localKey;
|
||||
ctx.effectiveFields.add(new RelationFieldImpl(
|
||||
name, field.type.element.context.typeProvider.intType, field.name));
|
||||
|
||||
if (!ctx.effectiveFields.any((f) => f.name == field.name)) {
|
||||
if (field.name != 'id' || !autoIdAndDateFields) {
|
||||
var rf = new RelationFieldImpl(name,
|
||||
field.type.element.context.typeProvider.intType, field.name);
|
||||
ctx.effectiveFields.add(rf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.relations[field.name] = relation;
|
||||
|
@ -172,7 +186,9 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
if (column?.type == null)
|
||||
throw 'Cannot infer SQL column type for field "${field.name}" with type "${field.type.name}".';
|
||||
ctx.columns[field.name] = column;
|
||||
ctx.effectiveFields.add(field);
|
||||
|
||||
if (!ctx.effectiveFields.any((f) => f.name == field.name))
|
||||
ctx.effectiveFields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,11 +153,14 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
args[field.name] = expr;
|
||||
}
|
||||
|
||||
b.statements.add(new Code('if (row.every((x) => x == null)) return null;'));
|
||||
b.statements
|
||||
.add(new Code('if (row.every((x) => x == null)) return null;'));
|
||||
b.addExpression(ctx.buildContext.modelClassType
|
||||
.newInstance([], args).assignVar('model'));
|
||||
|
||||
ctx.relations.forEach((name, relation) {
|
||||
if (!const [RelationshipType.hasOne, RelationshipType.belongsTo]
|
||||
.contains(relation.type)) return;
|
||||
var foreign = ctx.relationTypes[relation];
|
||||
var skipToList = refer('row')
|
||||
.property('skip')
|
||||
|
@ -248,6 +251,16 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
b.addExpression(refer('result').assign(
|
||||
refer('getOne').call([refer('executor')]).awaited));
|
||||
|
||||
// Fetch the results of @hasMany
|
||||
ctx.relations.forEach((name, relation) {
|
||||
if (relation.type == RelationshipType.hasMany) {
|
||||
// Call fetchLinked();
|
||||
var fetchLinked = refer('fetchLinked')
|
||||
.call([refer('result'), refer('executor')]).awaited;
|
||||
b.addExpression(refer('result').assign(fetchLinked));
|
||||
}
|
||||
});
|
||||
|
||||
b.addExpression(refer('result').returned);
|
||||
});
|
||||
});
|
||||
|
@ -258,6 +271,108 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// Create a Future<T> fetchLinked(T model, QueryExecutor), if necessary.
|
||||
if (ctx.relations.values.any((r) => r.type == RelationshipType.hasMany)) {
|
||||
clazz.methods.add(new Method((b) {
|
||||
b
|
||||
..name = 'fetchLinked'
|
||||
..modifier = MethodModifier.async
|
||||
..returns = new TypeReference((b) {
|
||||
b
|
||||
..symbol = 'Future'
|
||||
..types.add(ctx.buildContext.modelClassType);
|
||||
})
|
||||
..requiredParameters.addAll([
|
||||
new Parameter((b) => b
|
||||
..name = 'model'
|
||||
..type = ctx.buildContext.modelClassType),
|
||||
new Parameter((b) => b
|
||||
..name = 'executor'
|
||||
..type = refer('QueryExecutor')),
|
||||
])
|
||||
..body = new Block((b) {
|
||||
var args = <String, Expression>{};
|
||||
|
||||
ctx.relations.forEach((name, relation) {
|
||||
if (relation.type == RelationshipType.hasMany) {
|
||||
// For each hasMany, we need to create a query of
|
||||
// the corresponding type.
|
||||
var foreign = ctx.relationTypes[relation];
|
||||
var queryType = refer(
|
||||
'${foreign.buildContext.modelClassNameRecase.pascalCase}Query');
|
||||
var queryInstance = queryType.newInstance([]);
|
||||
|
||||
// Next, we need to apply a cascade that sets the correct query value.
|
||||
var localField = ctx.buildContext.fields.firstWhere(
|
||||
(f) =>
|
||||
ctx.buildContext.resolveFieldName(f.name) ==
|
||||
relation.localKey, orElse: () {
|
||||
throw '${ctx.buildContext.clazz.name} has no field that maps to the name "${relation.localKey}", '
|
||||
'but it has a @HasMany() relation that expects such a field.';
|
||||
});
|
||||
|
||||
var foreignField = foreign.buildContext.fields.firstWhere(
|
||||
(f) =>
|
||||
foreign.buildContext.resolveFieldName(f.name) ==
|
||||
relation.foreignKey, orElse: () {
|
||||
throw '${foreign.buildContext.clazz.name} has no field that maps to the name "${relation.foreignKey}", '
|
||||
'but ${ctx.buildContext.clazz.name} has a @HasMany() relation that expects such a field.';
|
||||
});
|
||||
|
||||
var queryValue =
|
||||
(localField.name == 'id' && autoIdAndDateFields)
|
||||
? 'int.parse(model.id)'
|
||||
: 'model.${localField.name}';
|
||||
var cascadeText =
|
||||
'..where.${foreignField.name}.equals($queryValue)';
|
||||
var queryText = queryInstance.accept(new DartEmitter());
|
||||
var combinedExpr =
|
||||
new CodeExpression(new Code('($queryText$cascadeText)'));
|
||||
|
||||
// Finally, just call get and await it.
|
||||
var expr = combinedExpr
|
||||
.property('get')
|
||||
.call([refer('executor')]).awaited;
|
||||
args[name] = expr;
|
||||
}
|
||||
});
|
||||
|
||||
// Just return a copyWith
|
||||
b.addExpression(
|
||||
refer('model').property('copyWith').call([], args).returned);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
// Also, if there is a @HasMany, generate overrides for query methods that
|
||||
// execute in a transaction, and invoke fetchLinked.
|
||||
if (ctx.relations.values.any((r) => r.type == RelationshipType.hasMany)) {
|
||||
for (var methodName in const ['get', 'update', 'delete']) {
|
||||
clazz.methods.add(new Method((b) {
|
||||
b
|
||||
..name = methodName
|
||||
..annotations.add(refer('override'))
|
||||
..requiredParameters.add(new Parameter((b) => b
|
||||
..name = 'executor'
|
||||
..type = refer('QueryExecutor')))
|
||||
..body = new Block((b) {
|
||||
var inTransaction = new Method((b) {
|
||||
b..modifier = MethodModifier.async
|
||||
..body = new Block((b) {
|
||||
var mapped = new CodeExpression(new Code('await Future.wait(result.map((m) => fetchLinked(m, executor)))'));
|
||||
b.addExpression(new CodeExpression(new Code('var result = await super.$methodName(executor)')));
|
||||
b.addExpression(mapped.returned);
|
||||
});
|
||||
});
|
||||
|
||||
b.addExpression(refer('executor')
|
||||
.property('transaction')
|
||||
.call([inTransaction.closure]).returned);
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ class PostgresExecutor extends QueryExecutor {
|
|||
|
||||
@override
|
||||
Future<T> transaction<T>(FutureOr<T> Function() f) async {
|
||||
if (connection is! PostgreSQLConnection) return await f();
|
||||
var old = connection;
|
||||
T result;
|
||||
try {
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import 'package:postgres/postgres.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'models/fruit.dart';
|
||||
import 'models/fruit.orm.g.dart';
|
||||
import 'models/tree.dart';
|
||||
import 'models/tree.orm.g.dart';
|
||||
import 'common.dart';
|
||||
|
||||
main() {
|
||||
PostgreSQLConnection connection;
|
||||
PostgresExecutor executor;
|
||||
Tree appleTree;
|
||||
int treeId;
|
||||
|
||||
setUp(() async {
|
||||
connection = await connectToPostgres(['tree', 'fruit']);
|
||||
appleTree = await TreeQuery.insert(connection, rings: 10);
|
||||
var query = new TreeQuery()..values.rings = 10;
|
||||
|
||||
executor = await connectToPostgres(['tree', 'fruit']);
|
||||
appleTree = await query.insert(executor);
|
||||
treeId = int.parse(appleTree.id);
|
||||
});
|
||||
|
||||
|
@ -33,34 +32,36 @@ main() {
|
|||
}
|
||||
|
||||
setUp(() async {
|
||||
apple = await FruitQuery.insert(
|
||||
connection,
|
||||
treeId: treeId,
|
||||
commonName: 'Apple',
|
||||
);
|
||||
var appleQuery = new FruitQuery()
|
||||
..values.treeId = treeId
|
||||
..values.commonName = 'Apple';
|
||||
|
||||
banana = await FruitQuery.insert(
|
||||
connection,
|
||||
treeId: treeId,
|
||||
commonName: 'Banana',
|
||||
);
|
||||
var bananaQuery = new FruitQuery()
|
||||
..values.treeId = treeId
|
||||
..values.commonName = 'Banana';
|
||||
|
||||
apple = await appleQuery.insert(executor);
|
||||
banana = await bananaQuery.insert(executor);
|
||||
});
|
||||
|
||||
test('can fetch any children', () async {
|
||||
var tree = await TreeQuery.getOne(treeId, connection);
|
||||
var query = new TreeQuery()..where.id.equals(treeId);
|
||||
var tree = await query.getOne(executor);
|
||||
verify(tree);
|
||||
});
|
||||
|
||||
test('sets on update', () async {
|
||||
var tq = new TreeQuery()..where.id.equals(treeId);
|
||||
var tree = await tq.update(connection, rings: 24).first;
|
||||
var tq = new TreeQuery()
|
||||
..where.id.equals(treeId)
|
||||
..values.rings = 24;
|
||||
var tree = await tq.updateOne(executor);
|
||||
verify(tree);
|
||||
expect(tree.rings, 24);
|
||||
});
|
||||
|
||||
test('sets on delete', () async {
|
||||
var tq = new TreeQuery()..where.id.equals(treeId);
|
||||
var tree = await tq.delete(connection).first;
|
||||
var tree = await tq.deleteOne(executor);
|
||||
verify(tree);
|
||||
});
|
||||
});
|
||||
|
|
8
angel_orm_generator/test/migrations/fruit.sql
Normal file
8
angel_orm_generator/test/migrations/fruit.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
CREATE TEMPORARY TABLE "fruits" (
|
||||
"id" serial,
|
||||
"tree_id" int,
|
||||
"common_name" varchar,
|
||||
"created_at" timestamp,
|
||||
"updated_at" timestamp,
|
||||
PRIMARY KEY(id)
|
||||
);
|
8
angel_orm_generator/test/migrations/tree.sql
Normal file
8
angel_orm_generator/test/migrations/tree.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
CREATE TEMPORARY TABLE "trees" (
|
||||
"id" serial,
|
||||
"rings" smallint UNIQUE,
|
||||
"created_at" timestamp,
|
||||
"updated_at" timestamp,
|
||||
UNIQUE(rings),
|
||||
PRIMARY KEY(id)
|
||||
);
|
|
@ -2,6 +2,141 @@
|
|||
|
||||
part of angel_orm_generator.test.models.tree;
|
||||
|
||||
// **************************************************************************
|
||||
// OrmGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class TreeQuery extends Query<Tree, TreeQueryWhere> {
|
||||
TreeQuery() {}
|
||||
|
||||
@override
|
||||
final TreeQueryValues values = new TreeQueryValues();
|
||||
|
||||
@override
|
||||
final TreeQueryWhere where = new TreeQueryWhere();
|
||||
|
||||
@override
|
||||
get tableName {
|
||||
return 'trees';
|
||||
}
|
||||
|
||||
@override
|
||||
get fields {
|
||||
return const ['id', 'rings', 'created_at', 'updated_at'];
|
||||
}
|
||||
|
||||
@override
|
||||
TreeQueryWhere newWhereClause() {
|
||||
return new TreeQueryWhere();
|
||||
}
|
||||
|
||||
static Tree parseRow(List row) {
|
||||
if (row.every((x) => x == null)) return null;
|
||||
var model = new Tree(
|
||||
id: row[0].toString(),
|
||||
rings: (row[1] as int),
|
||||
createdAt: (row[2] as DateTime),
|
||||
updatedAt: (row[3] as DateTime));
|
||||
return model;
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return parseRow(row);
|
||||
}
|
||||
|
||||
@override
|
||||
insert(executor) {
|
||||
return executor.transaction(() async {
|
||||
var result = await super.insert(executor);
|
||||
where.id.equals(int.parse(result.id));
|
||||
result = await getOne(executor);
|
||||
result = await fetchLinked(result, executor);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
Future<Tree> fetchLinked(Tree model, QueryExecutor executor) async {
|
||||
return model.copyWith(
|
||||
fruits: await (new FruitQuery()
|
||||
..where.treeId.equals(int.parse(model.id)))
|
||||
.get(executor));
|
||||
}
|
||||
|
||||
@override
|
||||
get(QueryExecutor executor) {
|
||||
return executor.transaction(() async {
|
||||
var result = await super.get(executor);
|
||||
return await Future.wait(result.map((m) => fetchLinked(m, executor)));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
update(QueryExecutor executor) {
|
||||
return executor.transaction(() async {
|
||||
var result = await super.update(executor);
|
||||
return await Future.wait(result.map((m) => fetchLinked(m, executor)));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
delete(QueryExecutor executor) {
|
||||
return executor.transaction(() async {
|
||||
var result = await super.delete(executor);
|
||||
return await Future.wait(result.map((m) => fetchLinked(m, executor)));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class TreeQueryWhere extends QueryWhere {
|
||||
final NumericSqlExpressionBuilder<int> id =
|
||||
new NumericSqlExpressionBuilder<int>('id');
|
||||
|
||||
final NumericSqlExpressionBuilder<int> rings =
|
||||
new NumericSqlExpressionBuilder<int>('rings');
|
||||
|
||||
final DateTimeSqlExpressionBuilder createdAt =
|
||||
new DateTimeSqlExpressionBuilder('created_at');
|
||||
|
||||
final DateTimeSqlExpressionBuilder updatedAt =
|
||||
new DateTimeSqlExpressionBuilder('updated_at');
|
||||
|
||||
@override
|
||||
get expressionBuilders {
|
||||
return [id, rings, createdAt, updatedAt];
|
||||
}
|
||||
}
|
||||
|
||||
class TreeQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
int get rings {
|
||||
return (values['rings'] as int);
|
||||
}
|
||||
|
||||
void set rings(int value) => values['rings'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(Tree model) {
|
||||
values.addAll({
|
||||
'rings': model.rings,
|
||||
'created_at': model.createdAt,
|
||||
'updated_at': model.updatedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
|
|
@ -13,6 +13,7 @@ part 'user.serializer.g.dart';
|
|||
class _User extends Model {
|
||||
String username, password, email;
|
||||
|
||||
@belongsToMany
|
||||
List<Role> roles;
|
||||
// TODO: Belongs to many
|
||||
//@belongsToMany
|
||||
//List<Role> roles;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,124 @@
|
|||
|
||||
part of angel_orm_generator.test.models.user;
|
||||
|
||||
// **************************************************************************
|
||||
// OrmGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class UserQuery extends Query<User, UserQueryWhere> {
|
||||
@override
|
||||
final UserQueryValues values = new UserQueryValues();
|
||||
|
||||
@override
|
||||
final UserQueryWhere where = new UserQueryWhere();
|
||||
|
||||
@override
|
||||
get tableName {
|
||||
return 'users';
|
||||
}
|
||||
|
||||
@override
|
||||
get fields {
|
||||
return const [
|
||||
'id',
|
||||
'username',
|
||||
'password',
|
||||
'email',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
UserQueryWhere newWhereClause() {
|
||||
return new UserQueryWhere();
|
||||
}
|
||||
|
||||
static User parseRow(List row) {
|
||||
if (row.every((x) => x == null)) return null;
|
||||
var model = new User(
|
||||
id: row[0].toString(),
|
||||
username: (row[1] as String),
|
||||
password: (row[2] as String),
|
||||
email: (row[3] as String),
|
||||
createdAt: (row[4] as DateTime),
|
||||
updatedAt: (row[5] as DateTime));
|
||||
return model;
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return parseRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
class UserQueryWhere extends QueryWhere {
|
||||
final NumericSqlExpressionBuilder<int> id =
|
||||
new NumericSqlExpressionBuilder<int>('id');
|
||||
|
||||
final StringSqlExpressionBuilder username =
|
||||
new StringSqlExpressionBuilder('username');
|
||||
|
||||
final StringSqlExpressionBuilder password =
|
||||
new StringSqlExpressionBuilder('password');
|
||||
|
||||
final StringSqlExpressionBuilder email =
|
||||
new StringSqlExpressionBuilder('email');
|
||||
|
||||
final DateTimeSqlExpressionBuilder createdAt =
|
||||
new DateTimeSqlExpressionBuilder('created_at');
|
||||
|
||||
final DateTimeSqlExpressionBuilder updatedAt =
|
||||
new DateTimeSqlExpressionBuilder('updated_at');
|
||||
|
||||
@override
|
||||
get expressionBuilders {
|
||||
return [id, username, password, email, createdAt, updatedAt];
|
||||
}
|
||||
}
|
||||
|
||||
class UserQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
String get username {
|
||||
return (values['username'] as String);
|
||||
}
|
||||
|
||||
void set username(String value) => values['username'] = value;
|
||||
String get password {
|
||||
return (values['password'] as String);
|
||||
}
|
||||
|
||||
void set password(String value) => values['password'] = value;
|
||||
String get email {
|
||||
return (values['email'] as String);
|
||||
}
|
||||
|
||||
void set email(String value) => values['email'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(User model) {
|
||||
values.addAll({
|
||||
'username': model.username,
|
||||
'password': model.password,
|
||||
'email': model.email,
|
||||
'created_at': model.createdAt,
|
||||
'updated_at': model.updatedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
@ -13,10 +131,8 @@ class User extends _User {
|
|||
this.username,
|
||||
this.password,
|
||||
this.email,
|
||||
List<Role> roles,
|
||||
this.createdAt,
|
||||
this.updatedAt})
|
||||
: this.roles = new List.unmodifiable(roles ?? []);
|
||||
this.updatedAt});
|
||||
|
||||
@override
|
||||
final String id;
|
||||
|
@ -30,9 +146,6 @@ class User extends _User {
|
|||
@override
|
||||
final String email;
|
||||
|
||||
@override
|
||||
final List<Role> roles;
|
||||
|
||||
@override
|
||||
final DateTime createdAt;
|
||||
|
||||
|
@ -44,7 +157,6 @@ class User extends _User {
|
|||
String username,
|
||||
String password,
|
||||
String email,
|
||||
List<Role> roles,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt}) {
|
||||
return new User(
|
||||
|
@ -52,7 +164,6 @@ class User extends _User {
|
|||
username: username ?? this.username,
|
||||
password: password ?? this.password,
|
||||
email: email ?? this.email,
|
||||
roles: roles ?? this.roles,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt);
|
||||
}
|
||||
|
@ -63,16 +174,13 @@ class User extends _User {
|
|||
other.username == username &&
|
||||
other.password == password &&
|
||||
other.email == email &&
|
||||
const ListEquality<Role>(const DefaultEquality<Role>())
|
||||
.equals(other.roles, roles) &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashObjects(
|
||||
[id, username, password, email, roles, createdAt, updatedAt]);
|
||||
return hashObjects([id, username, password, email, createdAt, updatedAt]);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
|
|
@ -13,11 +13,6 @@ abstract class UserSerializer {
|
|||
username: map['username'] as String,
|
||||
password: map['password'] as String,
|
||||
email: map['email'] as String,
|
||||
roles: map['roles'] is Iterable
|
||||
? new List.unmodifiable(((map['roles'] as Iterable)
|
||||
.where((x) => x is Map) as Iterable<Map>)
|
||||
.map(RoleSerializer.fromMap))
|
||||
: null,
|
||||
createdAt: map['created_at'] != null
|
||||
? (map['created_at'] is DateTime
|
||||
? (map['created_at'] as DateTime)
|
||||
|
@ -39,7 +34,6 @@ abstract class UserSerializer {
|
|||
'username': model.username,
|
||||
'password': model.password,
|
||||
'email': model.email,
|
||||
'roles': model.roles?.map((m) => m.toJson())?.toList(),
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
'updated_at': model.updatedAt?.toIso8601String()
|
||||
};
|
||||
|
@ -52,7 +46,6 @@ abstract class UserFields {
|
|||
username,
|
||||
password,
|
||||
email,
|
||||
roles,
|
||||
createdAt,
|
||||
updatedAt
|
||||
];
|
||||
|
@ -65,8 +58,6 @@ abstract class UserFields {
|
|||
|
||||
static const String email = 'email';
|
||||
|
||||
static const String roles = 'roles';
|
||||
|
||||
static const String createdAt = 'created_at';
|
||||
|
||||
static const String updatedAt = 'updated_at';
|
||||
|
|
Loading…
Reference in a new issue