How to get data using relationship - php

Please I want to make link using id (Semesters)
this how is my DB :
Courses: id , title , pdf_file , extension , description , matieres_id and timetables
Matieres: id , matiere , semester_id and timetables
Semesters: id , semester, matieres_id and timetables
route/web.php
Route::get('/lms/semestre', 'HomeController#semestres');
Route::get('/lms/', 'HomeController#lms');
Route::get('/lms/matieres/{id}', 'HomeController#matieres');
Route::get('/lms/course/{id}', 'HomeController#course');
Route::get('/lms/courses', 'HomeController#courses');
Course.php (model)
class Course extends Model
{
use SoftDeletes;
protected $table = 'courses';
protected $fillable = ['id'];
public function matiere()
{
return $this->belongsTo(\App\Matiere::class);
}
}
Matiere.php (Model)
class Matiere extends Model
{
protected $table = 'matieres';
protected $fillable = ['id'];
public function semestre()
{
return $this->belongsTo(\App\Semestre::class);
}
}
Semestre.php (Model)
class Semestre extends Model
{
protected $table = 'semestres';
protected $fillable = ['id'];
public function matiere()
{
return $this->belongsTo(\App\Matiere::class);
}
}
My issue is how to make url /lms/courses/{semester_id} and display a page where is courses list using course->matiere_id->semesters.
It's very complicated for me and I don't want to create column semester_id in course table.

Try this one.
Note: Make sure CourseDB is created first before SemesterDB
database:
course_db:
Schema::create('courses', function (Blueprint $table) {
...
});
semester_db:
Schema::create('semesters', function (Blueprint $table) {
...
$table->unsignedBigInteger('course_id');
...
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
})
Model:
course_model:
protected $guarded = [];
public function semester() {
return $this->hasOne(Semester::class);
}
semester_mode:
protected $guarded = [];
public function course() {
return $this->belongsTo(Course::class);
}
controller:
App\Course;
public function index() {
$courses = Course::all();
dd($courses->semester);
}

Related

How to restrict delete / destroy method when model has association with another model / id?

I have model called GroupService and it has association with Service. I want to prevent or restrict when deleting GroupService, if GroupService has association with Service. And if GroupService has no association then users can delete it. I've been following these guides but it's not working for me :
[1] Laravel - How to prevent delete when there is dependent field
[2] https://laracasts.com/discuss/channels/laravel/how-to-prevent-the-delete-of-table-row-that-has-its-id-in-another-table
Here's my code :
Model GroupService:
class GroupService extends Model
{
use HasFactory;
protected $table = 't_grup_layanan';
protected $guarded = ['id'];
// protected $fillable = [
// 'bisnis_id',
// 'deskripsi'
// ];
protected $with = ['business'];
public function service(){
return $this->hasMany(Service::class);
}
public function business(){
return $this->belongsTo(Business::class, 'bisnis_id');
}
// protected static function boot(){
// parent::boot();
// static::deleting(function($groupservice) {
// $relationMethods = ['service'];
// foreach ($relationMethods as $relationMethod) {
// if ($groupservice->$relationMethod()->count() > 0) {
// return false;
// }
// }
// });
// }
}
Model Service:
class Service extends Model
{
use HasFactory;
protected $table = 't_layanan';
protected $guarded = ['id'];
// protected $fillable = [
// 'gruplayanan_id',
// 'nama',
// 'deskripsi'
// ];
protected $with = ['groupservice'];
public function groupservice(){
return $this->belongsTo(GroupService::class, 'gruplayanan_id');
}
}
Controller GroupService:
public function destroy(GroupService $groupservice, $id)
{
$groupService = GroupService::find(Crypt::decrypt($id));
if ($groupService->service()->exists())
{
abort('Resource cannot be deleted due to existence of related resources.');
}
$groupService->delete();
return redirect('/dashboard/gruplayanan/')->with('danger', 'Data dihapus !');
}
Migration GroupService:
public function up()
{
Schema::create('t_grup_layanan', function (Blueprint $table) {
$table->id();
$table->foreignId('bisnis_id')->nullable()->index('fk_bisnis_to_group');
$table->text('deskripsi');
$table->timestamps();
});
}
Migration Service:
public function up()
{
Schema::create('t_layanan', function (Blueprint $table) {
$table->id();
$table->foreignId('gruplayanan_id')->index('fk_grup_to_layanan');
$table->text('nama');
$table->text('deskripsi');
$table->timestamps();
});
}
public function up()
{
Schema::table('t_layanan', function (Blueprint $table) {
$table->foreign('gruplayanan_id', 'fk_grup_to_layanan')->references('id')->on('t_grup_layanan')->onUpdate('CASCADE')->onDelete('CASCADE');
});
}
I think problem is here on your relationship function:
public function service(){
return $this->hasMany(Service::class);
}
By Laravel convention, Eloquent will take the table name parent model and suffix it with _id.
So it look for t_grup_layanan_id field in the t_layanan table which currently does not exist.
So if you want to override the default convention, you have to specify it on the 2nd parameter like this.
public function service(){
return $this->hasMany(Service::class, 'gruplayanan_id');
}

How to obtain three level model data laravel

Updated
User model
class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens, HasRoles;
const MALE = 'male';
const FEMALE = 'female';
protected $guard_name = 'sanctum';
public function educationalBackgrounds()
{
return $this->hasMany("App\Models\Users\EducationalBackground", "user_id");
}
public function seminars()
{
return $this->hasMany("App\Models\Users\Seminar", "user_id");
}
}
I have child table EducationalBackground which is related to User table
class EducationalBackground extends Model
{
use HasFactory;
protected $table = 'users.educational_backgrounds';
protected $fillable = [
'user_id',
'studies_type',
'year',
'course',
];
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
public function educationalAwards()
{
return $this->hasMany("App\Models\Users\EducationalAward", "educational_background_id");
}
}
And a third table that i want to access the award field
class EducationalAward extends Model
{
use HasFactory;
protected $table = 'users.educational_awards';
protected $fillable = [
'educational_background_id',
'award',
'photo',
];
public function educationalBackground()
{
return $this->belongsTo('App\Models\Users\EducationalBackground', 'educational_background_id');
}
}
I have api get route here
Route::get('/educational-background/{id}', [UserProfileController::class, 'getEducationalBackground']);
Here is my api method it works fine. But i want to go deeper and access the data of third table.
public function getEducationalBackground($id)
{
$educationalBackground = EducationalBackground::with('user')->where('user_id', $id)->get();
return response()->json($educationalBackground, 200);
}
It looks like you're not really grasping the concept of relations yet. Also, I'd advise you to look into route model binding :) What you basically want to be doing is:
public function getEducationalBackground($id)
{
$user = User::find($id);
return $user->educationalBackgrounds()->with('educationalAwards')->get();
}
Also, when you're pretty sure that whenever you want to use backgrounds, you also want to use the awards, you can add the with(...) to the model definition like so:
class EducationalBackground extends Model
{
...
protected $with = ['educationalAwards'];
}
That way, you can simplify your controller method to:
public function getEducationalBackground($id)
{
$user = User::find($id);
return $user->educationalBackgrounds;
}

Laravel One to One Relationship get object result is null

Migration persons Table:
Schema::create('persons', function (Blueprint $table) {
$table->id();
$table->string("firstname");
$table->string("lastname");
$table->timestamps();
});
Migration passports Table:
Schema::create('passports', function (Blueprint $table) {
$table->id();
$table->string("identifystring")->unique();
$table->unsignedBigInteger("person_id");
$table->timestamps();
$table->foreign("person_id")->references("id")->on("persons")->onDelete("cascade");
});
Person model:
class Person extends Model
{
use HasFactory;
protected $table ="persons";
protected $fillable = [
"firstname",
"lastname"
];
public function passport() {
$this->hasOne(\App\Models\Passport::class, "passports.person_id","persons.id");
}
}
Passport Model:
class Passport extends Model
{
use HasFactory;
protected $table = "passports";
protected $fillable = [
"identifystring",
"person_id"
];
}
execute Code:
$person = \App\Models\Person::findOrFail(2);
dd($person->passport());
Result is: null
class Person extends Model
{
use HasFactory;
protected $table ="persons";
protected $fillable = [
"firstname",
"lastname"
];
public function passport() {
$this->hasOne(\App\Models\Passport::class, "person_id", "id");
}
}
You did not return the relation. just return it:
public function passport() {
return $this->hasOne(\App\Models\Passport::class, "passports.person_id","persons.id");
}
As per the migrations written. In the Person model write
public function passport() {
return $this->hasOne(\App\Models\Passport::class, "person_id","id");
}
and in the Passport model write
public function person() {
return $this->belongsTo(\App\Models\Person::class, 'id', 'person_id');
}
Execute the code
$person = \App\Models\Person::findOrFail(2)->passport;
dd($person);
Use this code.
In your Person Model
public function passport() {
return $this->hasOne(\App\Models\Passport::class);
}
In your passport model
public function person() {
return $this->belongsTo(\App\Models\Person::class, 'person_id');
}
Then try to pass the relation again by doing the same thing
$person = \App\Models\Person::findOrFail(2);
dd($person->passport());

Laravel Error: Too few arguments to function Illuminate\Database\Eloquent\Model::setAttribute()

I am getting the following error while trying to insert into the table users_basics
Illuminate\Database\Eloquent\Model::setAttribute(), 1 passed in
C:\xampp\htdocs\msadi\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php
on line 592 and exactly 2 expected
Here is my controller code:
public function create()
{
$userId = '10';
$userBasics = new UserBasics;
$userBasics->user_id = $userId;
$userBasics->save();
return redirect('users');
}
Here is my model:
class UserBasics extends Model
{
protected $table = 'users_basics';
protected $primaryKey = null;
protected $fillable = ['user_id'];
const UPDATED_AT = null;
const CREATED_AT = null;
}
Here is my user_basics migration:
public function up()
{
Schema::create('users_basics', function (Blueprint $table) {
$table->integer('user_id');
$table->bigInteger('adhaar_no')->nullable();
$table->string('mobile_no')->nullable();
$table->string('college_roll_no')->nullable();
$table->date('dob')->nullable();
$table->index('user_id');
});
}
I have tried adding UPDATED_AT, CREATED_AT and PrimaryKey to the table but none worked. The user_id is being inserted into the users_basics table but the error continues to show.
You should modify your model:
class UserBasics extends Model
{
protected $table = 'users_basics';
protected $primaryKey = null;
public $incrementing = false;
public $timestamps = false;
protected $fillable = ['user_id'];
}
because you not have field for Timestamp.
please add like this.
public function up()
{
Schema::create('sadi_users_basics', function (Blueprint $table) {
$table->integer('user_id');
$table->bigInteger('adhaar_no')->nullable();
$table->string('mobile_no')->nullable();
$table->string('college_roll_no')->nullable();
$table->date('dob')->nullable();
$table->timestamp(); <---- just insert this.
$table->index('user_id');
});
}
also, if you want to use softdelete then add $table->softDeletes();
it will make Deleted_at field in the table.
enjoy coding~!

Laravel : Select from two tables where column in table two =value using eloquent

I have two tables
table 1 = NewsCollection
table 2 = NewsConllectionTranslation
here is the models
NewsCollection
class NewsCollection extends \Eloquent
{
use \Dimsav\Translatable\Translatable;
public $translatedAttributes = ['title', 'content'];
public $translationModel = 'NewsCollectionTranslation';
public function newsTrans()
{
return $this->hasMany('NewsCollectionTranslation', 'news_collection_id');
}
}
NewsConllectionTranslation
class NewsCollectionTranslation extends \Eloquent
{
public $timestamps = false;
protected $table = 'news_collection_translations';
protected $fillable = ['title', 'content'];
public function transNews()
{
return $this->belongsTo('NewsCollection', 'news_collection_id');
}
}
and here is the show controller
public function show($title)
{
$news = NewsConllectionTranslation::with('newsTrans')->where('title', $title)->first();
return View::make('portal.news.show', compact('news'));
}
What I need to do is
->where('title', $title)->first();
should be selected from NewsConllectionTranslation and I don't want to lose the translation so I don't want to select from NewsConllectionTrnslation first
You should try this:
$news = NewsConllectionTranslation::whereHas('newsTrans', function ($query) use ($title) {
$query->where('title', $title);
})->first();
Change your function like this
public function show($title)
{
$news = NewsConllectionTranslation::with(['newsTrans' => function ($query) use($title) {
$query->where('title', $title)->first();
}])
return View::make('portal.news.show', compact('news'));
}

Categories