many to many laravel get values - php

in user class model , i have this
public function projects()
{
return $this->belongsToMany('App\Project');
}
in project class model i have this :
public function users(){
return $this->belongsToMany('App\User');
}
in my projectController i have this :
public function index()
{
$TeamLeader = array();
$posts = Project::orderby('id', 'desc')->with('users')->paginate(5);
return view('Projects.index', compact('posts'));
}
in my view i have this for each :
#foreach ($posts as $post)
<tr>
<td><input type="checkbox" class="checkthis" /></td>
<td href="{{ route('Projects.show', $post->project_id ) }}">{{ $post->project_id }}</td>
<td>{{ $post->name }}</td>
<td>{{ $post->description }}</td>
<td>{{ $post->created_at }}</td>
<td>{{ $user->name}}</td>
<td><p data-placement="top" data-toggle="tooltip" title="Show"><button class="btn btn-primary btn-xs" data-title="Edit" data-toggle="modal" data-target="#show" ><span class="glyphicon glyphicon-pencil"></span></button></p></td>
<td><p data-placement="top" data-toggle="tooltip" title="Delete"><button class="btn btn-danger btn-xs" data-title="Delete" data-toggle="modal" data-target="#delete" ><span class="glyphicon glyphicon-trash"></span></button></p></td>
</tr>
#endforeach
my problem is , in my view i can not get the users name , the realation is many-to-many but iam not getting the names of the users who are involved in the project , the database structure is as you can imagine :
Users has id , name , ......
Projects has id , name , location , user_id , .....
sorry to not mention that earlier but i have this common table also :
Schema::create('project_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('project_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('project_id')->references('id')->on('projects');
$table->timestamps();
});

Actually your tables design is not many to many, It's one to many [User has many Project]
if you want to make many to many relation must make a middle table (pivot table)
take a look at this
This is helpful
Add this to your migrations
Schema::create('project_user', function(Blueprint $table)
{
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')
->on('users')->onDelete('cascade');
$table->integer('project_id')->unsigned()->nullable();
$table->foreign('project_id')->references('id')
->on('projects')->onDelete('cascade');
$table->timestamps();
});
project_user table is derived from the alphabetical order of the related model names, and contains the user_id and project_id columns
Then remove user_id column from your projects table
Finally yo can access the name of users like
$project->users[0]->name
$project->users[0]->name

Related

How to return specific assaing value from model when foreign key null Laravel

when a foreign key value is null I want to return a specific value from the model because when I delete the primary key id row and set a null value on the foreign key shows error. how to can I do it please anybody help me?
Here Is My Country Migration Table:
public function up()
{
Schema::create('countries', function (Blueprint $table) {
$table->id();
$table->string('name', 60)->nullable();
$table->string('country_code', 60)->nullable();
$table->string('capital', 120)->nullable();
$table->string('region', 120)->nullable();
$table->string('currency_code', 120)->nullable();
$table->string('currency_name', 120)->nullable();
$table->string('currency_symbol', 120)->nullable();
$table->string('language_code', 120)->nullable();
$table->string('language_name', 120)->nullable();
$table->bigInteger('flag')->unsigned()->nullable();
$table->foreign('flag')->references('id')->on('media_files')->onDelete('cascade')->onUpdate('cascade');
$table->string('dialling_code', 10)->nullable();
$table->integer('status')->default(0)->unsigned();
$table->timestamps();
});
}
Here Is My City migration Table:
Schema::create('cities', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('zipcode')->nullable();
$table->string('order')->default(null)->nullable();
$table->foreignId('country_id')->nullable()->constrained("countries")->cascadeOnUpdate()->nullOnDelete();
$table->timestamps();
});
City Model:
class City extends Model
{
use HasFactory;
public function country(){
return $this->belongsTo(Country::class,'country_id');
}
}
Frontend Blade:
<tbody>
#foreach($CityList as $City)
<tr>
<td><input type="checkbox" name="id[]"></td>
<td>{{$City->id }}</td>
<td>{{$City->name }}</td>
<td>{{$City->zipcode }}</td>
<td>{{$City->country->name }}</td>
<td>{{$City->country->countrycode }}</td>
<td>{{$City->order }}</td>
<td>{{$City->created_at->diffForHumans()}}</td>
<td>
<i class="fa fa-edit" style="font-size: 17px;"></i>
<button href="{{ route('dashboard.city.delete',$City->id) }}" type="button" value="{{ $City->id }}" class="btn btn-danger delete" data-toggle="tooltip" title="Delete">
<i aria-hidden="true" class="fa fa-trash"></i>
</button>
</td>
</tr>
#endforeach
</tbody>
I can suggest a few ways to solve this
First: Make a default value for the relation, like here
public function country()
{
return $this->belongsTo(...)->withDefault(['name' => 'No country']);
}
Second: Make a mutation in City model to find the name of the country
protected function countryName(): Attribute
{
return Attribute::make(
get: fn ($value) => $this->country-> name ?? 'Not country',
);
}
Notes: This way works only for laravel 9.x +, for older versions
please read this article
You can do this: <td>{{$City->country ? $City->country->name : 'No country found'}}</td>
And make sure you are including countries when fetching cities.

Laravel 5.8: How to show a column information of a pivot table in Many To Many relationship

I have a Many To Many relationship between User Model & Wallet Model:
Wallet.php:
public function users() {
return $this->belongsToMany(User::class,'user_wallet','user_id','wallet_id');
}
And User.php:
public function wallets() {
return $this->belongsToMany(Wallet::class,'user_wallet','user_id','wallet_id');
}
And the pivot table of this relationship goes like this:
So I can properly show Wallet name at the Blade:
#forelse($user->wallets as $wallet)
<tr>
<td>
{{ $wallet->name }}
</td>
<td>
{{ $wallet->balance }}
</td>
</tr>
#empty
<td colspan="5" class="text-center">
No wallet exist
</td>
#endforelse
But the wallet balance data does not appear (because it's in the pivot table and not the wallets table).
So how to show this custom column in this case?
use withPivot and mention additional column name
public function wallets()
{
return $this->belongsToMany(Wallet::class,'user_wallet','user_id','wallet_id')->withPivot('balance');
}
then in view
<td>{{ $wallet->pivot->balance }}</td>

parent id for category and subcategory

I use L8 And I have a category table ,it has parent_id for my subcategories
categories table
Category model
categoryController
SubCategoryController
categories.blade
sub_categories.blade
In my subcategory-index.blade.php I want to show categories but I just can show them with their id (parent id)
I don't know how to show categories title instead of their id.
I have this migration for categories table :
public function up()
{
Schema::dropIfExists('categories');
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('parent_id')->default(123);
$table->string('title');
$table->longText('description');
$table->tinyInteger('status')->comment('status is 1 when a category is active and it is 0 otherwise.')->nullable();
$table->rememberToken();
$table->softDeletes();
$table->timestamps();
});
}
and this is my category model :
class Category extends Model
{
use HasFactory;
protected $fillable = [
'parent_id','title' , 'description', 'status',
];
public function children(){
return $this->hasMany(Category::class , 'parent_id');
}
public function post(){
return $this->hasMany(Post::class);
}
}
And my subcategory controller :
...
public function index()
{
$parent_id = Category::with('parent_id')->get();
$subcategories = Category::where('parent_id' ,'!=', 123)->get();
return view('admin.subcategories.subcategories-index' , compact('subcategories'));
}
...
And the part for show subcategory title in category-index.blade.php :
<table class="table table-bordered">
<tr>
<th>#</th>
<th>id</th>
<th>title</th>
<th>category</th>
<th>status</th>
<th>operation</th>
</tr>
#foreach($subcategories as $subcategory )
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $subcategory['id'] }}</td>
<td>{{ $subcategory['title'] }}</td>
<td>{{ $subcategory['parent_id']}}</td>
<td>
#if($subcategory['status']==0 or $subcategory['status']==NULL)
inactive
#else
active
#endif
</td>
<td>
<form method="POST" action="{{ route('subcategory.destroy',$subcategory->id) }}">
<a class="btn btn-info" href="{{ route('subcategory.show' , $subcategory->id) }}">show</a>
<a class="btn btn-primary" href="{{ route('subcategory.edit' , $subcategory->id) }}">edit</a>
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger"> delete</button>
</form>
</td>
</tr>
#endforeach
</table>
Thanks for telling me what to do :>
To get subcategories
$sub_categories = Category::whereNotNull('parent_id')->get();
To get sub-categories with parent
$sub_categories_with_parent = Category::with('parent')->whereNotNull('parent_id')->get();
To fetch categories
$categories = Category::whereNull('parent_id')->get();
To fetch categories with children
$categories_with_childern = Category::with('children')->whereNull('parent_id')->get();
You might have to redefine your relations as well:
public function parent()
{
return $this->belongsTo(Category::class);
}
public function children()
{
return $this->hasMany(Category::class , 'parent_id');
}
In migration define relation as well
$table->foreign('parent_id')->references('id')->on('categories')->onUpdate('cascade')->onDelete('cascade');
Make parent field nullable
$table->unsignedBigInteger('parent_id')->nullable()->default(123);
The line down below is incorrect. Because with() is used to get relational data and parent_id is not a relation name.
$parent_id = Category::with('parent_id')->get();
If your route contains the id or slug of the category, you can use it, but I think it doesn't, because your index function doesn't accept any route parameter. So I assume you are trying to fetch all categories and subcategories. But in this case, the second line of the index function doesn't make sense at all.
If you want to all categories:
$categories = Category::where('parent_id', null)->with('children')->get();
I see you use 123 for top-level categories, and it looks high enough. But nullable is a better practice for that purpose.
If you need a specific category and its subcategories:
// web.php
Route::get('category/{slug}', [CategoryController::class, 'index']);
// CategoryConteroller.php
public function index($slug)
{
$category = Category::where('slug', $slug)->with('children')->get();
}

How to make relationships on two tables using fields that are not primary keys in both tables

i have no better way to explain this, this is what i want to do
i want to make a one to many relationship between a students table and a students marks table, but i want the students' registration number to relate the tables yet the students' registration number is neither a primary key in any of the two tables.
This is my students table
students table
this is my students results table
student results table
i have tried to look every where on how to do this but i have failed.
please dont be hash am a newbie
Please help me, am a laravel starter building a school project needed soon.
thanks in advance!
//Mark model.
public function student()
{
return $this->belongsTo(
Student::class,
'registration_number' //Field name in the student_marks table
'registration_number' //Field name in the students table
);
}
//Student model
public function marks()
{
return $this->hasMany(
Mark::class,
'registration_number', //Field name in the student_marks table
'registration_number', //Field name in the students table
);
}
Detail information about relationship defining;
https://laravel.com/api/5.4/Illuminate/Database/Eloquent/Concerns/HasRelationships.html
#foreach($marks as $mark)
<tr class="item{{$mark->id}}">
<td>{{ App\Students_mark::find($mark->id)->marks_for('Name_of_Student') }}</td>
<td>{{$mark->regno}}</td>
<td>{{$mark->course_unit_id}}</td>
<td>{{$mark->term_id}}</td>
<td>{{$mark->c_w_marks}}</td>
<td>{{$mark->e_o_t_marks}}</td>
<td>
<button class="show-modal btn btn-sm btn-success" data-id="{{$mark->id}}" data-name="{{$mark->regno}}" data-abbrev="{{$mark->course_unit_id}}" data-level="{{$mark->term_id}}" data-lecturer="{{$mark->c_w_mrks}}">
<span class="glyphicon glyphicon-eye-open"></span> View</button>
<button class="edit-modal btn btn-sm btn-info" data-id="{{$mark->id}}" data-name="{{$mark->regno}}" data-abbrev="{{$mark->course_unit_id}}" data-level="{{$mark->term_id}}" data-lecturer="{{$mark->c_w_mrks}}">
<span class="glyphicon glyphicon-edit"></span> Edit</button>
<button class="delete_data btn btn-sm btn-danger" data-id="{{$mark->id}}" data-name="{{$mark->regno}}">
<span class="glyphicon glyphicon-trash"></span> Delete</button>
</td>
</tr>
#endforeach
I tried Mutas' Relationship code and i hope it works but now am having another issue, i am trying to loop through the Students marks and then get the name of the student using the relation below
students registration model
public function marks(){
return $this->hasMany(
Students_mark::class,
'regno',
'RegNo'
);
}
students marks table
public function marks_for(){
return $this->belongsTo(
StudentsReg::class,
'regno',
'RegNo'
);
}
hope you understand me, am looking for a better way to explain this but i have failed!

Getting data from foreign key on view (Laravel 5.6)

I already searched for answers but I couldn't find any answer that could solve my problem.
I have 2 tables: phones and phone_types. The first one has a foreign key associated with the phone_types primary key. I want to show on view the name of phone_type through phone object. Something like $phone->phone_type->name.
My code generates this error: Trying to get property of non-object (View: /home/ablono/dev/MisServices/resources/views/painel/phones/home.blade.php)
My code is listed below.
phone_types miration table:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePhoneTypesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('phone_types', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 20);
$table->string('description', 30);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('phone_types');
}
}
```
phones migration table:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePhonesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('phones', function (Blueprint $table) {
$table->increments('id');
$table->string('ddd')->default('13');
$table->string('number', 20);
$table->integer('phone_type_id')->unsigned();
$table->foreign('phone_type_id')
->references('id')
->on('phone_types')
->onDelete('cascade');
$table->timestamps();
});
Schema::create('phone_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('phone_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->foreign('phone_id')
->references('id')
->on('phones')
->onDelete('cascade');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('phone_user');
Schema::dropIfExists('phones');
}
}
I didn't code anything on PhoneType model, but here is the code:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class PhoneType extends Model
{
//
}
Phone model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
public function users()
{
return $this->belongsToMany(\App\User::class);
}
public function phoneType()
{
return $this->hasMany(\App\PhoneType::class);
}
}
Method that is sending that to view:
public function index()
{
$phones = Phone::all();
return view('painel.phones.home', compact('phones'));
}
Part of view that is listing data:
<table class="table">
<thead>
<th>ID</th>
<th>DDD</th>
<th>Número</th>
<th>Tipo de Telefone</th>
<th width="150px">Ações</th>
</thead>
<tbody>
#foreach($phones as $phone)
<tr>
<div class="loading"></div>
<td>{{ $phone->id }}</td>
<td>{{ $phone->ddd }}</td>
<td>{{ $phone->number }}</td>
<td>{{ $phone->phone_type_id->name }}</td>
<td>
<i class="fa fa-lg fa-phone" title="Visualizar usuários que usam {{ $phone->number }}"></i>
<i class="fa fa-lg fa-pencil" title="Editar {{ $phone->number }}"></i>
<i class="fa fa-lg fa-times" title="Excluir {{ $phone->number }}"></i>
<i class="fa fa-lg fa-eye" title="Visualizar {{ $phone->number }}"></i>
</td>
</tr>
#endforeach
</tbody>
</table>
Change your relationship to belongsTo():
public function phoneType()
{
return $this->belongsTo(\App\PhoneType::class, 'phone_type_id');
}
And in view
<td>{{ $phone->phone_type->name }}</td>
Please check your eloquent model relationship. And accessing the eloquent property is like .
$main-model->$sub-model(method name of model which you want access)->property
Note: When you access method please convert method name in to snake case

Categories