سلام خسته نباشید
من به یک پروژه جالبی تو گیت هاب پیدا کردم که در مورد زمان بندی و برنامه ریزی مدارس بود
چیز جالبی که باعث شد مغزم 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();
});
}
}
داداش من کد رو دانلود کردم
جدول رابطه رو جدا تعریف کرده مایگریشن جدا
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');
});
}سلام
داداش مایگریشن رو اشتباه نوشته باید بزاره class_id رو توی جدول lesson
اگر توی مدل مربوطه دقت کنی خودش ارجاع داده به این فیلد
public function classLessons()
{
return $this->hasMany(Lesson::class, 'class_id', 'id');
}
لاراول از روی این رابطه ای که توی مدل نوشته شده میفهمه و اسم فیلد مربوطه رو هم نوشته همینجا که چیه اما توی مایگریشن یادش رفته که بزاره
توی fillable چیزایی رو میزاری که میخوایی دستی مثلا create کنی و روابط نیازی نیست کلیداش گزاشته بشه و نباید بزاری توی fillable
به نظر من اشتباه هست قضیه
@salar.mohammad2013
یعنی طرف یادش رفته یا از روی عمد کلید خارجی ننوشته !
داخل مایگرشن lessen
شاید پاسخ شما همینجا باشد
این یک روش استاندارد هست که اول جداول نوشته میشوند سپس رابطه ها و این امر به این دلیل هست که اگر توجه کرده باشید زمانی که دستور مایگریت رو میزنید فایل به فایل اقدام به تولید جدول میکنه و اگر شما جداول پیجیده ای داشته باشید که دارای ارتباطا های زیادی هست ممکن جدول الف با جدول ب ارتباط داشته باشه و چون هنوز جدول ب تولید نشده ماگریشن ارور تیبل نات فایند میده و جداول ساخته نمیشن.
اما راه درست این هست که ابتدا همه جداول ساخته میشند سپس روابط ایجاد میشن تا دچار خطای تیبل نات فایند در دستور مایگریشن نشن