Open szymjab opened 6 months ago
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Post extends Model
{
use HasFactory;
protected $fillable = ['title', 'content'];
public static function createFromString(string $post): self
{
$postArray = json_decode($post, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \InvalidArgumentException('Invalid JSON string');
}
return new self([
'title' => $postArray['title'] ?? '',
'content' => $postArray['content'] ?? ''
]);
}
public static function createEmpty(): self
{
return new self([
'title' => '',
'content' => ''
]);
}
}
namespace App\Http\Controllers;
use App\Http\Requests\CreatePostFromStringRequest;
use App\Http\Requests\CreateEmptyPostRequest;
use App\Models\Post;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function storeFromString(CreatePostFromStringRequest $request): JsonResponse
{
try {
$post = Post::createFromString($request->input('post_data'));
$post->save();
return response()->json(['message' => 'Post created successfully', 'post' => $post], 201);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 400);
}
}
public function storeEmpty(CreateEmptyPostRequest $request): JsonResponse
{
try {
$post = Post::createEmpty();
$post->save();
return response()->json(['message' => 'Empty post created successfully', 'post' => $post], 201);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 400);
}
}
}
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreatePostFromStringRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'post_data' => 'required|string',
];
}
}
....
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateEmptyPostRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [];
}
}
Route::resource('posts', PostController::class);
https://github.com/ProgrammingPiotrN/ProjectNewWork/blob/907a705ab417ca83ee2a85d00276f19b4765db8f/Blog/app/Models/Post.php#L8
Laravel narzuca pewną konwencję - zachęca do tworzenia relacji poprzez wbudowane mechanizmy oraz zachęca do tworzenia nowych encji z użyciem istniejących metod
create
lubsave
.Nie jest to dobre jeśli tworzymy obiekt odzwierciedlający naszą dziedzinę (DDD). Powoduje to, że nasz obiekt jest tylko gołym nośnikiem danych o relacjach.
W związku z tym zaleca się stosowanie statycznych metod wytwórczych, które pozwolą na tworzenie prawidłowego obiektu, zgodnego z naszymi założeniami biznesowymi.
Dla przykładu, obiekt
Geolocation
mógłby zostać utworzony na różne sposoby:Wówczas przydatne mogą być metody:
Geolocation::createFromArray(array $data): self
Geolocation::createFromString(string $geolocation): self
Geolocation::createEmpty(): self
Dzięki temu zakodowaliśmy wszystkie założenia biznesowe, jednocześnie w każdej z tych metod możemy kontrolować logikę, wg której są one tworzone - np. obiekt geolocation nie może być utworzony przy użyciu metodycreateFromString
podając jako argument ciąg znaków krótszy niż 3 znaki.Konkretne informacje zawarte są w książce, którą podesłałem na maila :)