متین طیبی نیا
1 سال پیش توسط متین طیبی نیا مطرح شد
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


ثبت پرسش جدید
محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 1 سال پیش مطرح شد
0

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

    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');
        });
    }

محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 1 سال پیش مطرح شد
0

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

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

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


متین طیبی نیا
تخصص : backend
@MatinTayebi 1 سال پیش آپدیت شد
0

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


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 1 سال پیش مطرح شد
0

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

    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');
        });
    }

متین طیبی نیا
تخصص : backend
@MatinTayebi 1 سال پیش مطرح شد
1

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


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 1 سال پیش مطرح شد
1

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


حسین افتخارراد
تخصص : نال کد
@hosseinradvictor 1 سال پیش مطرح شد
2

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

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


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

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