feat: save meal

This commit is contained in:
Leon Morival 2026-05-15 22:43:58 +02:00
parent 5ee10cb8b5
commit 425d0d2498
5 changed files with 45 additions and 10 deletions

View File

@ -9,6 +9,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Storage;
class MealPostController extends Controller
{
@ -18,6 +19,7 @@ class MealPostController extends Controller
$mealPosts = MealPosts::query()
->where('user_id', $request->user()->getKey())
->with('user:id,name,avatar_url')
->latest('eaten_at')
->paginate($perPage)
->withQueryString();
@ -28,10 +30,12 @@ class MealPostController extends Controller
public function store(MealPostsRequest $request): JsonResponse
{
$mealPost = MealPosts::create([
...$request->validated(),
...$this->getValidatedDataWithImageUrl($request),
'user_id' => $request->user()->getKey(),
]);
$mealPost->setRelation('user', $request->user());
return (new MealPostsResource($mealPost))
->response()
->setStatusCode(201);
@ -41,16 +45,16 @@ class MealPostController extends Controller
{
$this->abortIfNotOwner($request, $mealPost);
return new MealPostsResource($mealPost);
return new MealPostsResource($mealPost->loadMissing('user:id,name,avatar_url'));
}
public function update(MealPostsRequest $request, MealPosts $mealPost): MealPostsResource
{
$this->abortIfNotOwner($request, $mealPost);
$mealPost->update($request->validated());
$mealPost->update($this->getValidatedDataWithImageUrl($request));
return new MealPostsResource($mealPost->refresh());
return new MealPostsResource($mealPost->refresh()->loadMissing('user:id,name,avatar_url'));
}
public function destroy(Request $request, MealPosts $mealPost): Response
@ -67,4 +71,18 @@ class MealPostController extends Controller
abort_unless($request->user(), 401);
abort_unless($mealPost->user_id === $request->user()->getKey(), 404);
}
private function getValidatedDataWithImageUrl(MealPostsRequest $request): array
{
$data = $request->validated();
if ($request->hasFile('image')) {
$path = $request->file('image')->store('meal-posts', 'public');
$data['image_url'] = asset(Storage::url($path));
}
unset($data['image']);
return $data;
}
}

View File

@ -9,7 +9,8 @@ class MealPostsRequest extends FormRequest
public function rules(): array
{
return [
'image_url' => ['required', 'string', 'url', 'max:255'],
'image' => ['sometimes', 'nullable', 'image', 'max:4096'],
'image_url' => ['required_without:image', 'nullable', 'string', 'url', 'max:2048'],
'caption' => ['nullable', 'string', 'max:1000'],
'calories' => ['nullable', 'integer', 'min:0'],
'proteins' => ['nullable', 'numeric', 'min:0'],
@ -24,4 +25,12 @@ class MealPostsRequest extends FormRequest
{
return true;
}
public function messages(): array
{
return [
'image.max' => "L'image ne doit pas dépasser 4 Mo.",
'image_url.required_without' => "Ajoute une image au repas.",
];
}
}

View File

@ -5,12 +5,15 @@ namespace App\Http\Resources;
use App\Models\MealPosts;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Storage;
/** @mixin MealPosts */
class MealPostsResource extends JsonResource
{
public function toArray(Request $request): array
{
$user = $this->user;
return [
'id' => $this->id,
'imageUrl' => $this->image_url,
@ -24,7 +27,11 @@ class MealPostsResource extends JsonResource
'createdAt' => $this->created_at,
'updatedAt' => $this->updated_at,
'userId' => $this->user_id,
'user' => [
'name' => $user?->name,
'avatarUrl' => $user?->avatar_url ? asset(Storage::url($user->avatar_url)) : null,
'id' => $user->id,
],
];
}
}

View File

@ -2,6 +2,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -9,7 +10,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
class MealPosts extends Model
{
use HasFactory, SoftDeletes;
use HasFactory, HasUlids, SoftDeletes;
protected $fillable = [
'user_id',
@ -31,7 +32,7 @@ class MealPosts extends Model
protected function casts(): array
{
return [
'eaten_at' => 'timestamp',
'eaten_at' => 'datetime',
];
}
}

View File

@ -8,9 +8,9 @@ return new class extends Migration {
public function up(): void
{
Schema::create('meal_posts', function (Blueprint $table) {
$table->id();
$table->ulid('id')->primary();
$table->foreignUlid('user_id')->constrained('users')->cascadeOnDelete();
$table->string('image_url');
$table->string('image_url', 2048);
$table->text('caption')->nullable();
$table->integer('calories')->nullable();
$table->decimal('proteins',8,2)->nullable();