راکت
حل شده

ربات بودن کلید خارجی در لاراول

6 پاسخ

سلام خسته نباشید
من به یک پروژه جالبی تو گیت هاب پیدا کردم که در مورد زمان بندی و برنامه ریزی مدارس بود
چیز جالبی که باعث شد مغزم fatal error بده 😁
این که تو جدول school_classesو lessens (که رابطشون یک به چند هستش )
هیچ foreign key تو جدول lessens نبود ولی این دو جدول با هم ارتباط داشتن و موقع تعریف متتد ارتباط داخل model اسم کلید نوشته شده بود . و در پراپرتی fillable مدل Lessen اسم کلیدی که در متتد ارتباط نوشته شده بود، در اون نوشته شده بود
من کد کلاس مایگریشن و مدل ها رو براتون میزارم و لینک ریپو هم این زیر مینویسم :
گیت هاب

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class SchoolClass extends Model
{
    use SoftDeletes;

    public $table = 'school_classes';

    protected $dates = [
        'created_at',
        'updated_at',
        'deleted_at',
    ];

    protected $fillable = [
        'name',
        'created_at',
        'updated_at',
        'deleted_at',
    ];

    public function classLessons()
    {
        return $this->hasMany(Lesson::class, 'class_id', 'id');
    }

    public function classUsers()
    {
        return $this->hasMany(User::class, 'class_id', 'id');
    }
}
<?php

namespace App;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Lesson extends Model
{
    use SoftDeletes;

    public $table = 'lessons';

    protected $dates = [
        'created_at',
        'updated_at',
        'deleted_at',
    ];

    protected $fillable = [
        'weekday',
        'class_id',
        'end_time',
        'teacher_id',
        'start_time',
        'created_at',
        'updated_at',
        'deleted_at',
    ];

    const WEEK_DAYS = [
        '1' => 'Monday',
        '2' => 'Tuesday',
        '3' => 'Wednesday',
        '4' => 'Thursday',
        '5' => 'Friday',
        '6' => 'Saturday',
        '7' => 'Sunday',
    ];

    public function getDifferenceAttribute()
    {
        return Carbon::parse($this->end_time)->diffInMinutes($this->start_time);
    }

    public function getStartTimeAttribute($value)
    {
        return $value ? Carbon::createFromFormat('H:i:s', $value)->format(config('panel.lesson_time_format')) : null;
    }

    public function setStartTimeAttribute($value)
    {
        $this->attributes['start_time'] = $value ? Carbon::createFromFormat(config('panel.lesson_time_format'),
            $value)->format('H:i:s') : null;
    }

    public function getEndTimeAttribute($value)
    {
        return $value ? Carbon::createFromFormat('H:i:s', $value)->format(config('panel.lesson_time_format')) : null;
    }

    public function setEndTimeAttribute($value)
    {
        $this->attributes['end_time'] = $value ? Carbon::createFromFormat(config('panel.lesson_time_format'),
            $value)->format('H:i:s') : null;
    }

    function class()
    {
        return $this->belongsTo(SchoolClass::class, 'class_id');
    }

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

    public static function isTimeAvailable($weekday, $startTime, $endTime, $class, $teacher, $lesson)
    {
        $lessons = self::where('weekday', $weekday)
            ->when($lesson, function ($query) use ($lesson) {
                $query->where('id', '!=', $lesson);
            })
            ->where(function ($query) use ($class, $teacher) {
                $query->where('class_id', $class)
                    ->orWhere('teacher_id', $teacher);
            })
            ->where([
                ['start_time', '<', $endTime],
                ['end_time', '>', $startTime],
            ])
            ->count();

        return !$lessons;
    }

    public function scopeCalendarByRoleOrClassId($query)
    {
        return $query->when(!request()->input('class_id'), function ($query) {
            $query->when(auth()->user()->is_teacher, function ($query) {
                $query->where('teacher_id', auth()->user()->id);
            })
                ->when(auth()->user()->is_student, function ($query) {
                    $query->where('class_id', auth()->user()->class_id ?? '0');
                });
        })
            ->when(request()->input('class_id'), function ($query) {
                $query->where('class_id', request()->input('class_id'));
            });
    }
}

مایگریشن ها

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateSchoolClassesTable extends Migration
{
    public function up()
    {
        Schema::create('school_classes', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
            $table->softDeletes();
        });
    }
}
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateLessonsTable extends Migration
{
    public function up()
    {
        Schema::create('lessons', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('weekday');
            $table->time('start_time');
            $table->time('end_time');
            $table->timestamps();
            $table->softDeletes();
        });
    }
}

@Raymond
@salar.mohammad2013
@javadkarimii
@hussain2

ثبت پرسش جدید

پاسخ‌ها

6
محمد رضا
محمد رضا
@salar.mohammad2013

تخصص: Full Stack Developer

بهترین پاسخ

داداش من کد رو دانلود کردم
جدول رابطه رو جدا تعریف کرده مایگریشن جدا

    public function up()
    {
        Schema::table('lessons', function (Blueprint $table) {
            $table->unsignedInteger('teacher_id');
            $table->foreign('teacher_id', 'teacher_fk_1001496')->references('id')->on('users');
            $table->unsignedInteger('class_id');
            $table->foreign('class_id', 'class_fk_1001508')->references('id')->on('school_classes');
        });
    }
محمد رضا
محمد رضا
@salar.mohammad2013

تخصص: Full Stack Developer

سلام
داداش مایگریشن رو اشتباه نوشته باید بزاره class_id رو توی جدول lesson
اگر توی مدل مربوطه دقت کنی خودش ارجاع داده به این فیلد

    public function classLessons()
    {
        return $this->hasMany(Lesson::class, 'class_id', 'id');
    }

لاراول از روی این رابطه ای که توی مدل نوشته شده میفهمه و اسم فیلد مربوطه رو هم نوشته همینجا که چیه اما توی مایگریشن یادش رفته که بزاره
توی fillable چیزایی رو میزاری که میخوایی دستی مثلا create کنی و روابط نیازی نیست کلیداش گزاشته بشه و نباید بزاری توی fillable
به نظر من اشتباه هست قضیه

متین طیبی نیا
متین طیبی نیا
@MatinTayebi

تخصص: backend

@salar.mohammad2013
یعنی طرف یادش رفته یا از روی عمد کلید خارجی ننوشته !
داخل مایگرشن lessen

شاید پاسخ شما همین‌جا باشد

متین طیبی نیا
متین طیبی نیا
@MatinTayebi

تخصص: backend

اها 😅
شرمنده دقت نکردم بهش

محمد رضا
محمد رضا
@salar.mohammad2013

تخصص: Full Stack Developer

اره منم انتظار نداشتم جدا باشه مایگریشنش فک کردم اشتباه کرده یادش رفته بزاره
بعد دیدم که نه روشش متفاوت بوده همین

حسین افتخارراد
حسین افتخارراد
@hosseinradvictor

تخصص: نال کد

این یک روش استاندارد هست که اول جداول نوشته میشوند سپس رابطه ها و این امر به این دلیل هست که اگر توجه کرده باشید زمانی که دستور مایگریت رو میزنید فایل به فایل اقدام به تولید جدول میکنه و اگر شما جداول پیجیده ای داشته باشید که دارای ارتباطا های زیادی هست ممکن جدول الف با جدول ب ارتباط داشته باشه و چون هنوز جدول ب تولید نشده ماگریشن ارور تیبل نات فایند میده و جداول ساخته نمیشن.

اما راه درست این هست که ابتدا همه جداول ساخته میشند سپس روابط ایجاد میشن تا دچار خطای تیبل نات فایند در دستور مایگریشن نشن

برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام