اذهب إلى المحتوى

السؤال

نشر (معدل)

لدي جدولين واحد فيه المستخدم و اخر فيه صور خاصة بالمستخدم و اذا اريد احفظ forgien key الخاص بالمستخدم في جدول الصور لابد ان يحفظ المستخدم ثم اخذ قيمة user->id و اضعه في جدول الصور في خانة fk_user_id لكن كيف اجعل جدول الصور يخزن الصور مباشرة بعد ان يتم تخزين المستخدم؟ حاولت ولكن لا يوجد حل

تم التعديل في بواسطة Mustafa Suleiman
تعديل عنوان السؤال

Recommended Posts

  • 0
نشر

هل تقصد أنك أنشأت مسارين ؟ أى لإضافة المستخدم مسار ولإضافة الصور مسار ؟

إذا كان الأمر كذلك فهذا ليس جيدا يمكنك جعلهم مسار واحد بما أنه يتم إرسال البيانات من نموذج بيانات واحد أما لو كان هناك نموذجين يمكنك أولا إضافة المستخدم وبعد ذلك عند تحميل الصفحة للنموذج الثاني تقوم بوضع id المستخدم في action الخاص بالنموذج form .

أما بخصوص التخزين في قاعدة البيانات فأفضل طريقة هي من خلال العلاقات relations في laravel .

ففي نموذج User نضيف العلاقة التالية :

class User extends Model
{    
    public function images()
    {
        return $this->hasMany(Image::class, 'fk_user_id');
    }
}

وفي نموذج Image نضيف العلاقة التالية :

class Image extends Model
{    
    public function user()
    {
        return $this->belongsTo(User::class, 'fk_user_id');
    }
}

الآن عند إضافة المستخدم يمكنك ربط الصورة مباشرة به من خلال العلاقة التي أنشأناها هكذا :

$user = User::create([
    'name' => 'user_name',
    'email' => 'email@email.com',
    'password' => Hash::make('password')
]);

$path = $request->file('image')->store('user_images');
$user->images()->create([
'path' => $path
]);
 

وفي السطر الأخير هنا يمكنك إضافة بيانات الصورة التي تريد حفظها في قاعدة البيانات وسيتم ربطها مباشرة بهذا المستخدم.

  • 0
نشر

لن تستطيع حفظ سجل في جدول الصور images يعتمد على مفتاح أجنبي fk_user_id قبل أن يكون المستخدم user قد حُفظ بالفعل وحصل على id.

الحل هو في ترتيب العمليات واستخدام المعاملات Transactions لضمان أن كل شيء يتم بنجاح أو لا شيء يتم على الإطلاق، أولاً في نموذج app/Models/User.php عليك تعريف العلاقات كالتالي:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];



    public function images()
    {

        return $this->hasMany(Image::class, 'fk_user_id', 'id');
    }
}

المهم هو تحديد العلاقة في دالة images.

ثم في النموذج app/Models/Image.php:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Image extends Model
{
    use HasFactory;

    protected $fillable = [
        'fk_user_id',
        'path', // أو اسم الحقل الذي يخزن مسار الصورة
        'original_name',
    ];

    public function user()
    {
        return $this->belongsTo(User::class, 'fk_user_id', 'id');
    }
}

ثم في الـ Controller الخاص بمعالجة ذلك وليكن UserController أو RegisterController:

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; 
use Illuminate\Support\Facades\Hash; 
use Illuminate\Support\Facades\Storage; 

class UserController extends Controller
{
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8|confirmed',
            'user_images.*' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048' // 'user_images' هو اسم حقل الإدخال للملفات
        ]);

        DB::beginTransaction(); // ابدأ المعاملة

        try {
            $user = User::create([
                'name' => $validatedData['name'],
                'email' => $validatedData['email'],
                'password' => Hash::make($validatedData['password']),
            ]);

            if ($request->hasFile('user_images')) {
                foreach ($request->file('user_images') as $file) {
                    $path = $file->store('user_photos', 'public');

                    $user->images()->create([
                        'path' => $path,
                        'original_name' => $file->getClientOriginalName(),
                    ]);


                }
            }

            DB::commit(); 

            return response()->json(['message' => 'User and images saved successfully!', 'user_id' => $user->id], 201);

        } catch (\Exception $e) {
            DB::rollBack(); 

            return response()->json(['message' => 'Failed to save user and images.', 'error' => $e->getMessage()], 500);
        }
    }
}

$request->hasFile('user_images') يتحقق هل الطلب يحتوي على ملفات بالاسم user_images ويجب أن يكون ذلك هو الـ name الخاص بالحقل  في نموذج HTML:

 <input type="file" name="user_images[]" multiple>

و $file->store('user_photos', 'public') يخزن الملف الفعلي ويجب عليك إعداد قرص التخزين public وتشغيل أمر php artisan storage:link لجعل الملفات قابلة للوصول عبر الويب.

و $user->images()->create([]) تعتمد على العلاقة hasMany (images()) التي عرفناها في نموذج User، حيث يقوم Eloquent تلقائيًا بملء حقل fk_user_id بـ $user->id.

  • 0
نشر

السلام عليكم ورحمة الله وبركاته،

عندما نرغب في حفظ مستخدم جديد وربط مجموعة من الصور به في Laravel فإن الخطوة الأهم هي ضمان تنفيذ العمليات بترتيب صحيح أي أن نقوم أولا بحفظ المستخدم ثم نربط الصور باستخدام المعرف (ID) الذي حصل عليه.

وللقيام بذلك بطريقة فعالة، نبدأ بتعريف العلاقة بين النموذجين أي في نموذج المستخدم User.php نضيف دالة images() تخبر Laravel أن المستخدم يمتلك عدة صور، وذلك عبر علاقة hasMany كالتالي:

public function images()
{
    return $this->hasMany(Image::class, 'fk_user_id');
}

أما في نموذج الصور Image.php فنعرّف علاقة عكسية باستخدام belongsTo، حتى تتمكن الصورة من معرفة المستخدم المرتبطة به:

public function user()
{
    return $this->belongsTo(User::class, 'fk_user_id');
}

وبعد ضبط العلاقات ننتقل إلى تنفيذ عملية الحفظ داخل المتحكم Controller وأول ما نقوم به حينها هو التحقق من صحة البيانات القادمة من النموذج، بما في ذلك الصور، باستخدام التابع validate هكذا:

$user = User::create([
    'name' => $validated['name'],
    'email' => $validated['email'],
    'password' => Hash::make($validated['password']),
]);

ثم نتحقق ما إذا كانت هناك صور مرفقة مع الطلب فإذا وجدت، نقوم بتخزين كل صورة في مجلد مخصص باستخدام store()، ثم نربطها بالمستخدم الجديد باستخدام العلاقة images() التي عرفناها سابقا:

if ($request->hasFile('images')) {
    foreach ($request->file('images') as $file) {
        $path = $file->store('user_images', 'public');

        $user->images()->create([
            'path' => $path,
            'original_name' => $file->getClientOriginalName(),
        ]);
    }
}

وأخيرا نعيد ردا يفيد بأن كل شيء تم بنجاح:

return response()->json(['message' => 'User and images saved successfully']);

أما في واجهة المستخدم أي في ال form فيجب التأكد من أن الحقل الخاص بالصور يقبل ملفات متعددة، وذلك باستخدام multiple مع اسم يحتوي على أقواس مربعة بهذا الشكل:

<input type="file" name="images[]" multiple>

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...