āĻ¸ā§āĻ•āĻŋāĻĒ āĻ•āϰ⧇ āĻŽā§‚āϞ āĻ•āĻ¨ā§āĻŸā§‡āĻ¨ā§āϟ āĻ āϝāĻžāύ

📄 Gen Model Command

Individual model class generation commandāĨ¤

đŸŽ¯ Overview​

flx gen model command āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āφāĻĒāύāĻŋ standalone model class āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύāĨ¤ āĻāϟāĻŋ āĻŦāĻŋāĻļ⧇āώāĻ­āĻžāĻŦ⧇ useful āϝāĻ–āύ āφāĻĒāύāĻžāϰ āĻļ⧁āϧ⧁ āĻāĻ•āϟāĻŋ model class āĻĻāϰāĻ•āĻžāϰāĨ¤

📋 Basic Usage​

# Basic model generation
flx gen model User

# Model with specific location
flx gen model Product --path lib/models

# Model with custom properties
flx gen model Order --props id,userId,total

âš™ī¸ Command Options​

Basic Options​

flx gen model <name> [options]

Options:
--path, -p Output directory path
--props Comma-separated properties
--extends Parent class to extend
--implements Interfaces to implement
--freezed Generate with Freezed annotations
--json Add JSON serialization
--equatable Add Equatable support
--help, -h Show help

Property Types​

# String properties
flx gen model User --props "name:String,email:String"

# Mixed types
flx gen model Product --props "id:String,price:double,isActive:bool"

# Optional properties
flx gen model Profile --props "name:String,bio:String?,avatar:String?"

# List properties
flx gen model Order --props "id:String,items:List<OrderItem>"

# DateTime properties
flx gen model Event --props "title:String,date:DateTime,endDate:DateTime?"

📁 Generated Files​

Basic Model​

flx gen model User --props "id:String,name:String,email:String"

Generated file: lib/models/user_model.dart

class UserModel {
final String id;
final String name;
final String email;

const UserModel({
required this.id,
required this.name,
required this.email,
});

factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'] as String,
name: json['name'] as String,
email: json['email'] as String,
);
}

Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'email': email,
};
}

UserModel copyWith({
String? id,
String? name,
String? email,
}) {
return UserModel(
id: id ?? this.id,
name: name ?? this.name,
email: email ?? this.email,
);
}


bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is UserModel &&
other.id == id &&
other.name == name &&
other.email == email;
}


int get hashCode {
return id.hashCode ^ name.hashCode ^ email.hashCode;
}


String toString() {
return 'UserModel(id: $id, name: $name, email: $email)';
}
}

Model with Freezed​

flx gen model Product --props "id:String,name:String,price:double" --freezed

Generated file: lib/models/product_model.dart

import 'package:freezed_annotation/freezed_annotation.dart';

part 'product_model.freezed.dart';
part 'product_model.g.dart';


class ProductModel with _$ProductModel {
const factory ProductModel({
required String id,
required String name,
required double price,
}) = _ProductModel;

factory ProductModel.fromJson(Map<String, dynamic> json) =>
_$ProductModelFromJson(json);
}

Model with Entity Extension​

flx gen model UserModel --extends UserEntity --props "accessToken:String"

Generated file: lib/models/user_model.dart

import '../entities/user_entity.dart';

class UserModel extends UserEntity {
final String accessToken;

const UserModel({
required super.id,
required super.name,
required super.email,
required this.accessToken,
});

factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'] as String,
name: json['name'] as String,
email: json['email'] as String,
accessToken: json['access_token'] as String,
);
}


Map<String, dynamic> toJson() {
final json = super.toJson();
json['access_token'] = accessToken;
return json;
}

UserModel copyWith({
String? id,
String? name,
String? email,
String? accessToken,
}) {
return UserModel(
id: id ?? this.id,
name: name ?? this.name,
email: email ?? this.email,
accessToken: accessToken ?? this.accessToken,
);
}
}

🔧 Advanced Examples​

Complex Model with Nested Objects​

flx gen model Order --props "id:String,customer:Customer,items:List<OrderItem>,totalAmount:double,status:OrderStatus,createdAt:DateTime"
import 'customer.dart';
import 'order_item.dart';
import 'order_status.dart';

class OrderModel {
final String id;
final Customer customer;
final List<OrderItem> items;
final double totalAmount;
final OrderStatus status;
final DateTime createdAt;

const OrderModel({
required this.id,
required this.customer,
required this.items,
required this.totalAmount,
required this.status,
required this.createdAt,
});

factory OrderModel.fromJson(Map<String, dynamic> json) {
return OrderModel(
id: json['id'] as String,
customer: Customer.fromJson(json['customer'] as Map<String, dynamic>),
items: (json['items'] as List)
.map((item) => OrderItem.fromJson(item as Map<String, dynamic>))
.toList(),
totalAmount: (json['total_amount'] as num).toDouble(),
status: OrderStatus.values.firstWhere(
(status) => status.name == json['status'],
),
createdAt: DateTime.parse(json['created_at'] as String),
);
}

Map<String, dynamic> toJson() {
return {
'id': id,
'customer': customer.toJson(),
'items': items.map((item) => item.toJson()).toList(),
'total_amount': totalAmount,
'status': status.name,
'created_at': createdAt.toIso8601String(),
};
}

// ... copyWith, equality, toString methods
}

Model with Validation​

flx gen model RegistrationModel --props "name:String,email:String,password:String,age:int" --validate
class RegistrationModel {
final String name;
final String email;
final String password;
final int age;

const RegistrationModel({
required this.name,
required this.email,
required this.password,
required this.age,
});

factory RegistrationModel.fromJson(Map<String, dynamic> json) {
final model = RegistrationModel(
name: json['name'] as String,
email: json['email'] as String,
password: json['password'] as String,
age: json['age'] as int,
);

model.validate();
return model;
}

Map<String, dynamic> toJson() {
return {
'name': name,
'email': email,
'password': password,
'age': age,
};
}

void validate() {
final errors = <String>[];

if (name.trim().isEmpty) {
errors.add('Name is required');
}

if (!_isValidEmail(email)) {
errors.add('Invalid email format');
}

if (password.length < 8) {
errors.add('Password must be at least 8 characters');
}

if (age < 18) {
errors.add('Age must be at least 18');
}

if (errors.isNotEmpty) {
throw ValidationException(errors);
}
}

bool _isValidEmail(String email) {
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
}

// ... rest of the methods
}

class ValidationException implements Exception {
final List<String> errors;

ValidationException(this.errors);


String toString() => 'Validation failed: ${errors.join(', ')}';
}

Model with Equatable​

flx gen model TaskModel --props "id:String,title:String,completed:bool" --equatable
import 'package:equatable/equatable.dart';

class TaskModel extends Equatable {
final String id;
final String title;
final bool completed;

const TaskModel({
required this.id,
required this.title,
required this.completed,
});

factory TaskModel.fromJson(Map<String, dynamic> json) {
return TaskModel(
id: json['id'] as String,
title: json['title'] as String,
completed: json['completed'] as bool,
);
}

Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'completed': completed,
};
}

TaskModel copyWith({
String? id,
String? title,
bool? completed,
}) {
return TaskModel(
id: id ?? this.id,
title: title ?? this.title,
completed: completed ?? this.completed,
);
}


List<Object?> get props => [id, title, completed];


String toString() {
return 'TaskModel(id: $id, title: $title, completed: $completed)';
}
}

📋 Property Type Mapping​

Input TypeDart TypeJSON Handling
StringStringjson['key'] as String
String?String?json['key'] as String?
intintjson['key'] as int
doubledouble(json['key'] as num).toDouble()
boolbooljson['key'] as bool
DateTimeDateTimeDateTime.parse(json['key'])
DateTime?DateTime?json['key'] != null ? DateTime.parse(json['key']) : null
List<String>List<String>List<String>.from(json['key'])
List<Model>List<Model>(json['key'] as List).map((e) => Model.fromJson(e)).toList()
MapMap<String, dynamic>json['key'] as Map<String, dynamic>

đŸŽ¯ Real-World Examples​

E-commerce Product Model​

flx gen model ProductModel --props "id:String,name:String,description:String,price:double,discountPrice:double?,category:Category,images:List<String>,inStock:bool,tags:List<String>,createdAt:DateTime,updatedAt:DateTime"

User Profile Model​

flx gen model UserProfileModel --props "id:String,firstName:String,lastName:String,email:String,phoneNumber:String?,dateOfBirth:DateTime?,avatar:String?,address:Address?,preferences:Map<String,dynamic>,isVerified:bool,createdAt:DateTime"

API Response Model​

flx gen model ApiResponseModel --props "success:bool,message:String,data:Map<String,dynamic>?,errors:List<String>?,timestamp:DateTime" --generic

🔍 Model Templates​

Custom Templates​

Create custom model templates in templates/model/:

// templates/model/base_model.dart.mustache
class {{className}} {
{{#properties}}
final {{type}} {{name}};
{{/properties}}

const {{className}}({
{{#properties}}
{{#required}}required {{/required}}this.{{name}},
{{/properties}}
});

// Custom business logic methods
{{#hasBusinessMethods}}
{{#businessMethods}}
{{method}}
{{/businessMethods}}
{{/hasBusinessMethods}}

// Standard methods
factory {{className}}.fromJson(Map<String, dynamic> json) {
return {{className}}(
{{#properties}}
{{name}}: {{jsonParsing}},
{{/properties}}
);
}

Map<String, dynamic> toJson() {
return {
{{#properties}}
'{{jsonKey}}': {{jsonSerialization}},
{{/properties}}
};
}
}

Use Custom Template​

flx gen model CustomModel --template base_model --props "id:String,value:double"

đŸ§Ē Testing Integration​

Generate with Tests​

flx gen model UserModel --props "id:String,name:String" --with-tests

Generated test file: test/models/user_model_test.dart

import 'package:flutter_test/flutter_test.dart';
import 'package:myapp/models/user_model.dart';

void main() {
group('UserModel', () {
test('should create instance from JSON', () {
// Arrange
final json = {
'id': '123',
'name': 'John Doe',
};

// Act
final user = UserModel.fromJson(json);

// Assert
expect(user.id, '123');
expect(user.name, 'John Doe');
});

test('should convert to JSON', () {
// Arrange
const user = UserModel(
id: '123',
name: 'John Doe',
);

// Act
final json = user.toJson();

// Assert
expect(json['id'], '123');
expect(json['name'], 'John Doe');
});

test('should create copy with updated fields', () {
// Arrange
const user = UserModel(
id: '123',
name: 'John Doe',
);

// Act
final updatedUser = user.copyWith(name: 'Jane Doe');

// Assert
expect(updatedUser.id, '123');
expect(updatedUser.name, 'Jane Doe');
});

test('should implement equality correctly', () {
// Arrange
const user1 = UserModel(id: '123', name: 'John');
const user2 = UserModel(id: '123', name: 'John');
const user3 = UserModel(id: '456', name: 'Jane');

// Assert
expect(user1, equals(user2));
expect(user1, isNot(equals(user3)));
});
});
}

✅ Best Practices​

  1. Naming Convention: Use Model suffix for model classes
  2. Property Types: Be specific with property types
  3. Null Safety: Use nullable types appropriately
  4. JSON Keys: Follow API naming conventions
  5. Validation: Add validation for critical models
  6. Documentation: Document complex properties
  7. Testing: Generate tests for important models
  8. Immutability: Keep models immutable

🐛 Troubleshooting​

Common Issues​

# Invalid property syntax
flx gen model User --props "name,email"
Error: Property 'name' missing type. Use 'name:String'

# Invalid type
flx gen model User --props "name:InvalidType"
Error: Unknown type 'InvalidType'

# Missing required arguments
flx gen model
Error: Model name is required

Debug Mode​

# Show what will be generated
flx gen model User --props "name:String" --dry-run

# Verbose output
flx gen model User --props "name:String" --verbose

Individual models āϤ⧈āϰāĻŋ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ: flx gen model command perfect tool! 📄