How to set the field can be null when there is relationship - php

I have an issue, when I delete a contractor that relate to that one residence, there will be an error something like trying to get property name in this line in index view <li>Contractor: {{$res->contractor->name}}. I want to make it possible by deleting the contractor, then the contractor field in residence view could be empty or null. And this can be vice versa. How can I do that? Here is my model.
Residential.php
class Residential extends Model
{
protected $fillable = ['name','res_code','postcode','city','state','image','contractor_id'];
public function contractor()
{
return $this->belongsTo(Contractor::class);
}
public function buyer()
{
return $this->hasMany(Buyer::class);
}
}
Contractor.php
class Contractor extends Model
{
protected $table = 'contractors';
protected $fillable = ['name','address','phone_no','email','avatar'];
public function residential()
{
return $this->hasMany(Residential::class);
}
public function users()
{
return $this->morphMany(User::class, 'typable');
}
}
Here is my controller.
ResidentialController.php
class ResidentialController extends Controller
{
public function index(Request $request)
{
$contractor = Contractor::find($request->id);
$residential = Residential::all();
return view('residentials.index',compact('residential','contractor'));
}
ContractorController.php
public function index(Request $request)
{
$residential = Residential::find($request->id);
$contractor = Contractor::all();
return view('admins.contractors.index', compact('residential', 'contractor'));
}
And here is my view.
residentials\index.blade.php
#foreach($residential as $res)
<div class="panel-body">
<ul class="list-unstyled list-justify">
<li>ID: {{$res->id}}</li>
<li>Code: {{$res->res_code}}</li>
<li>Postcode: {{$res->postcode}}</li>
<li>City: {{$res->city}}</li>
<li>State: {{$res->state}}</li>
<li>Contractor: {{$res->contractor->name}}
</ul>
</div>
#endforeach
contractors\index.blade.php
<table class="table table-hover" id="contractor-table">
<tr>
<th>ID</th>
<th>Company</th>
<th>Phone No</th>
<th>Email</th>
<th>Residence</th>
<th>Action</th>
</tr>
#foreach($contractor as $cont)
<tr class="contractor{{$cont->id}}">
<td>{{$cont->id}}</td>
<td>{{$cont->name}}</td>
<td>{{$cont->phone_no}}</td>
<td>{{$cont->email}}</td>
<td>{{$cont->residential->pluck('name')->implode(', ')}}</td>
#endforeach
</table>
I hope there is someone can understand my problem and can help me.

You have to use LEFT JOIN in your query.Using of it you will automatic receive NULL value.
The SQL LEFT JOIN returns all rows from the left table, even if there are no matches in the right table. This means that if the ON clause matches 0 (zero) records in the right table; the join will still return a row in the result, but with NULL in each column from the right table.
This means that a left join returns all the values from the left table, plus matched values from the right table or NULL in case of no matching join predicate.
Reference link : https://www.tutorialspoint.com/sql/sql-left-joins.htm#:~:text=Advertisements,column%20from%20the%20right%20table.

Related

select desired column from pivot table and show in view

These are my model i want to show some desired column in my view as you can see but the issue is that the desired column like employ name employ no is getting from employ table but course name is not showing or displaying in view table. Is there a way to show the course name in course column in view.
This is my View
<table border="1">
<tr>
<th>Full name</th>
<th>Emp no</th>
<th>salary</th>
<th>course</th>
</tr>
#foreach($data as $item)
<tr>
<th>{{$item['Full_name']}} </th>
<th>{{$item['emp_no']}}</th>
<th>{{$item['salary']}}</th>
<th>
#foreach ($data->courses as $course)
{{$course->course_name}}
#endforeach
<th>
</tr>
#endforeach
</table>
This is my employ model class:
class employ extends Model
{
use HasFactory;
public $timestamps = false;
protected $guarded = [];
public function courses() {
return $this->belongsToMany(course::class, 'employ_course');
}
}
This is my course model class:
class course extends Model
{
use HasFactory;
public $timestamps = false;
protected $guarded = [];
public function employs() {
return $this->belongsToMany(employ::class, 'employ_course');
}
}
And this is my employ_course(pivot table) model class:
class employcourse extends Model
{
use HasFactory;
protected $guarded = [];
}
This is my controller:
public function show()
{
$datas = employ::with([('course')
=> function ($query) {
$query=course::select('course_name');
}])
->select('Full_name', 'salary', 'emp_no')
->get();
return view('teacher.teacher_data', ['datas' => $datas]);
}
in your nested #foreach in view $data should be $item to iterate over all courses from employee.
Then in your controller the $data could be like this:
$datas = employ::with('course')
->select('employ.Full_name', 'employ.salary', 'employ.emp_no', 'course.course_name')
->get();
Remember that class names must start with uppercase letters and database rows with lowercase.
You can achieve that goal with this:
public function show()
{
// you need the employ "id" column to retrieve the related courses
$datas = employ::with('courses:course_name')->get(['id', 'Full_name', 'salary', 'emp_no']);
return view('teacher.teacher_data', ['datas' => $datas]);
}
And your view, I think should be as following:
<table border="1">
<tr>
<th>Full name</th>
<th>Emp no</th>
<th>salary</th>
<th>courses</th>
</tr>
#foreach($data as $item)
<tr>
<td>{{$item['Full_name']}}</td>
<td>{{$item['emp_no']}}</td>
<td>{{$item['salary']}}</td>
<td>
#foreach ($data->courses as $course)
{{$course->course_name}}
#endforeach
</td>
</tr>
#endforeach
</table>

Laravel - PDOException::("SQLSTATE[42S02]: Base table or view not found: 1146 Table 'vestibulare.app\models\telefone' doesn't exist

I'm new to Laravel.
I'm trying to access some data from within a partial view.
I tried to put my query inside the boot method of AppServiceProvider, but Im getting this error:
PDOException::("SQLSTATE[42S02]: Base table or view not found: 1146 Table 'vestibulare.app\models\telefone' doesn't exist")
I can't even run php artisan serve.
Why is Laravel assuming my model's name is in the singular?
Here are my models:
class Usuario extends Model
{
protected $table = 'usuarios';
public $timestamps = false;
protected $fillable = [
'nome'
];
public function telefones()
{
return $this->hasMany(Telefone::class, 'id_usuario');
}
}
class Telefone extends Model
{
protected $table = 'telefones';
public $timestamps = false;
protected $casts = [
'id_usuario' => 'int'
];
protected $fillable = [
'id_usuario',
'numero'
];
public function usuario()
{
return $this->belongsTo(Usuario::class, 'id_usuario');
}
}
Here's the boot method inside app\Providers\AppServiceProvider class:
public function boot()
{
$data = Usuario::join(Telefone::class, "usuarios.id", "=", "telefones.id_usuario")
->select(
"usuarios.id as u.id",
"usuarios.nome as nome",
"telefones.numero as numero",
DB::raw("COUNT(numero) AS numero_count")
)
->groupBy("nome")
->orderBy("nome")
->get();
view()->with(["data" => $data]);
}
Initially, the query inside boot method was inside my controller's index method, like so:
class ContactListController extends Controller
{
public function index()
{
// $usuarios = Usuario::all();
// $telefones = Telefone::all();
$data = Usuario::join(Telefone::class, "usuarios.id", "=", "telefones.id_usuario")
->select(
"usuarios.id as u.id",
"usuarios.nome as nome",
"telefones.numero as numero",
DB::raw("COUNT(numero) AS numero_count")
)
->groupBy("nome")
->orderBy("nome")
->get();
return view("index", compact("data"));
}
{...}
}
Why am I getting this error?
How can I access the data I want from within the partial data?
Here are my views:
index.blade.php
<html>
#include("header")
#include("search_contact")
#include("contact_list")
#include("footer")
</html>
contact_list.blade.php <- I want to access data from here
<div class="col-lg-8">
<table id="myTable" class="table text-justify table-striped">
<thead class="tableh1">
<th class="">Name</th>
<th class="col-3">Nº of Phones</th>
<th class="">Phone</th>
</thead>
<tbody id="tableBody">
#foreach ($data as $item)
<tr>
<!-- Test -->
<td>{{ $item }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
I've been reading the docs, watching tutorials and searching for similar questions for over 6 hours. Please help me.
Thank you in advance.
Edit:
I've tried changing the query to the following:
$data = Usuario::join("telefones", "usuarios.id", "=", "telefones.id_usuario")
->select(
"usuarios.id as u.id",
"usuarios.nome as nome",
"telefones.numero as numero",
DB::raw("COUNT(telefones.numero) AS numero_count")
)
->groupBy("nome")
->orderBy("nome")
->get();
Where insteaad of using Telefone::class I'm now using telefones. I got a different error:
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'vestibulare.usuarios.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by (SQL: select `usuarios`.`id` as `u.id`, `usuarios`.`nome` as `nome`, `telefones`.`numero` as `numero`, COUNT(telefones.numero) AS numero_count from `usuarios` inner join `telefones` on `usuarios`.`id` = `telefones`.`id_usuario` group by `nome` order by `nome` asc)
Edit 2:
I've changed the following line inside my database.php config file:
'mysql' => [
...
'strict' => true,
...
]
To:
'mysql' => [
...
'strict' => false,
...
]
Now I'm not getting the above error anymore, but there's something wrong with my query because it's coming back empty.
Maybe do you try with DB?
\DB::table('usuarios')->join('telefones', ....
This is what I will do
class Usuario extends Model {
public $timestamps = false;
protected $table = 'usuarios';
protected $with=['telefonos'];
protected $fillable = [
'nome'
];
public function telefones()
{
return $this->hasMany(Telefone::class);
}
}
class Telefone extends Model {
protected $table = 'telefones';
public $timestamps = false;
protected $fillable = [
'id_usuario',
'numero'
];
public function usuario()
{
return $this->belongsTo(Usuario::class);
}
}
//Here's the boot method inside app\Providers\AppServiceProvider class:
// do not use this for querys to database
public function boot()
{
}
class ContactListController extends Controller {
public function index()
{
$usuarios = Usuario::all();
return view("index", $usuarios);
}
{...}
}
// And your view
<div class="col-lg-8">
<table id="myTable" class="table text-justify table-striped">
<thead class="tableh1">
<th class="">Name</th>
<th class="col-3">Nº of Phones</th>
<th class="">Phone</th>
</thead>
<tbody id="tableBody">
#foreach ($usuarios as $usuario)
<tr>
#php
$telefono = $usuario->tefono ?? 'This user has no telephone';
#endphp
<td>Nome: {{$usuario->nome}} Telef: {{$telefono}} </td>
</tr>
#endforeach
</tbody>
</table>
</div>
And finally return mysql values to original state.

count(): Parameter must be an array or an object that implements Countable in Laravel 6

I want to display data from multiple table to one view, first table is Transaction_in and second table is Transaction_in_detail but beside those two other table are involved.
This is Transcation_in Controller
class Transactions_inController extends Controller
{
public function show($id)
{
$supplierList = Supplier::where('id', 'nama')->first();
$transactionin = Transaction_in::where('id', $id)->first();
$deviceTypeList = DeviceType::where('id', 'nama_tipe_device')->first();
$deviceBrandList = DeviceBrand::where('id', 'nama_brand_device')->first();
$transactionindetail = Transaction_in_detail::where('id', 'Transansaction_in_id')->first();
//return view('transactionsin.show', compact('supplierList', 'transactionsin', 'deviceTypeList', 'deviceBrandList', 'transactionindetail'));
return view('transactionsin.show')->with('transactionsin', $transactionin);
return view('transactionsin.show')->with('transactionsindetail', $transactionindetail);
}
}
Transaction_in Model
class Transaction_in extends Model
{
protected $guarded = [];
public function get_suppliers()
{
return $this->belongsTo(Supplier::class, 'Supplier_id');
}
public function get_devicetypes()
{
return $this->belongsToMany(DeviceType::class, 'DeviceType_id');
}
public function get_devicebrands()
{
return $this->belongsToMany(DeviceBrand::class, 'DeviceBrand_id');
}
public function get_transactionindetail()
{
return $this->belongsToMany(Transaction_in_detail::class, 'Transaction_in_id');
}
}
Transaction_in_detail Model
class Transaction_in_detail extends Model
{
protected $guarded = [];
public function get_transction_in_id()
{
return $this->belongsTo(Transaction_in::class, 'Transaction_in_id');
}
public function get_devicetypes()
{
return $this->belongsToMany(DeviceType::class, 'DeviceType_id');
}
public function get_devicebrands()
{
return $this->belongsToMany(DeviceBrand::class, 'DeviceBrand_id');
}
}
I want to display data from Transaction_in_detail table to Transaction_in Controller, but i have this error
count(): Parameter must be an array or an object that implements
Countable (View:
C:\xampp\htdocs\inventory\resources\views\transactionsin\show.blade.php)
and this is transactionsin.show code https://hastebin.com/ilewesucej.xml
What does your table setup look like, specifically what is the relationship between Transaction_in and Transaction_in_detail? You have a One To Many relationship given in Transaction_in_detail::get_transaction_in_id and a Many to Many relationship given in Transaction_in::get_transactionindetail.
The belongsToMany relationship is for Many to Many relationships with a pivot table. Maybe this is supposed to be hasMany instead?
Start by clarifying that relationship correctly. See the docs on relationships in Laravel. Then you can pull the correct data.
Are you trying to get ONE Transaction_in instance with the id $id? In that case, no, you can't iterate over it. Maybe you're trying for something like this?
$transactionin = Transaction_in::find($id);
$transactionindetail = $transactionin->get_transactionindetail;
// $transactionindetail will now be a `Collection` which implements `Countable`.
Also note that you're (and some of the other answers) are mixing up transactionsin and transactionin (without the 's').
1.
You are using first() method which returns a single object , not array. Instead of returning a collection of models, first() method returns a single model instance. Rewrite your code as following -
$transactionin = Transaction_in::where('id', $id)->get();
For reference, Laravel Docs
2.
You don't have to return view and variables twice. Return once as following -
return view('transactionsin.show',compact('transactionsin','transactionsindetail'));
You don't need to return view two times. use compact for set multiple variable.
public function show($id)
{
$supplierList = Supplier::where('id', 'nama')->first();
$transactionin = Transaction_in::where('id', $id)->first();
$deviceTypeList = DeviceType::where('id', 'nama_tipe_device')->first();
$deviceBrandList = DeviceBrand::where('id', 'nama_brand_device')->first();
$transactionindetail = Transaction_in_detail::where('id', 'Transansaction_in_id')->first();
//return view('transactionsin.show', compact('supplierList', 'transactionsin', 'deviceTypeList', 'deviceBrandList', 'transactionindetail'));
return view('transactionsin.show',compact('transactionsin','transactionsindetail'));
}
In blade file check with empty condition.
#if (!empty($transactionsin))
<div class="tale-responsive">
<table class="table table-hover table-bordered">
<thead align="center">
<tr class="table-primary">
<th>Tipe Perangkat</th>
<th>Brand Perangkat</th>
<th>Spesifikasi</th>
<th>Jumlah</th>
<th>Harga</th>
<th>Total Harga</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ $transactionin->get_devicetypes->nama_tipe_device }}</td>
<td>{{ $transactionin->get_devicebrands->nama_brand_device }}</td>
<td>{{ $transactionin->get_transactionindetail->spek_device }}</td>
<td>{{ $transactionin->get_transactionindetail->harga_device }}</td>
<td>{{ $transactionin->get_transactionindetail->jumlah_device }}</td>
<td>{{ $transactionin->get_transactionindetail->total_harga_device }}</td>
</tr>
</tbody>
</table>
</div>
#else
<h6>No Data Found</h6>
#endif
if you want to make object countable you have to use $object->count()in your case $transactionin->count()

Data fetching in a one to many relationship in laravel

I want to fetch data from my database but I am stuck when I try to get data from another table.
This is what I want to do, when a user login to the web page, he would be able to see a list of people name. By clicking on their name, user will be redirected to another page which will show the person details such as name, address and email. But because there is so many of them (assuming around 200 people)
Questions:
Q1. how do I redirect the user to another page which is the name (eg: jack, user click on jack name, jack id = 1, how do I relate it back to the user_id = 1 which is the foreign key)
Q2. how do I do a loop to get their information instead of specifying it 1 by 1 (eg: I don't want to keep saying id=1, is there something like id++ which will help auto add)
This is how it looks like with my code: (picture I took from the internet but it something similar to this)
home.blade.php
<table class="table table-bordered">
<tr>
<th><strong><big>Name AS PER NRIC/PASSPORT: </big></strong></th>
</tr>
<td>
<tr>
#foreach($data as $value)
<tr>
<th> {{$value->Name}}</th> --> I don't know how to redirect it to show user details
</tr>
#endforeach
</tr>
</tr>
</table>
Controller
public function index()
{
return view('home');
}
public function getData(){
$data['data'] = DB::table('personal_infos')->get()->sortByDesc('upload_time');
if(count($data)>0){
return view('home',$data);
}else{
return view('home');
}
}
}
Route
Route::get('/test','testController#getData');
personal_info model
class personal_info extends Eloquent
{
protected $fillable = array('Email', 'Name', 'address');
protected $table = 'personal_infos';
protected $primaryKey = 'id';
public function user_infos() {
return $this->hasMany('App\user_info,'user_id');
}
public function user_info1s() {
return $this->hasMany('App\user_info1','user_id');
}
}
user_info and user_info1 model
class user_info1 extends Eloquent
{
protected $fillable = array('hobby','sport','user_id');
public function personal_infos() {
return $this->belongsTo('App\personal_info', 'user_id', 'id');
}
First add a route like
Route::get('/test/{id}','testController#getPerson')->name("showPerson");
Then setup a redirect
<a href="{{route('showPerson', $value)}}">
Use this line instead of your href="www.google.com"
Make getPerson() from testController return a new page, on that page, print out all the info of a person.
I would also suggest you google Laracast and watch all of the free videos. They're about 30 and they give you a good understanding of the laravel framework
Alter the link of your page to redirect you to the detail page:
<th> {{$value->Name}}</th>
route should be:
Route::get('user/show/{id}','testController#getInfo')->name("user.show");
controller should be:
public function getInfo($id) {
$user_info1 = user_info1::where('user_id',$id)->get();
return $user_info1;//change this with your view
}

Display name instead of id. Laravel

I have two tables; Students and Grade. Students contains foreign key grade_id referencing Grade.
For viewing students, I have used following code;
Controller:
public function viewStudent()
{
$students=Student::all();
return $students('grade_id');
$grade = Grade::find($id, ['id', 'grade_name']);
return view('students.view',compact('students'));
}
View:
<tbody>
#foreach($students as $student)
<tr class="info">
<td>{{$student->first_name}}</td>
<td>{{$student->middle_name}}</td>
<td>{{$student->last_name}}</td>
<td>{{$student->grade_id}}</td>
</tr>
#endforeach
</tbody>
Model:
class student extends Model
{
//
protected $fillable = ['first_name','middle_name','last_name','grade_id'];
}
It shows grade_id as i have called it. But I want grade_name instead of that. Can anyone help me?
First you need to define a relation to Grade in your student model:
class student extends Model
{
public function grade() {
return $this->belongsTo(Grade::class);
}
}
Then you should be able to eagerly load grades for students with
$students = Student::with('grade')->get();
and access student's grade name with
$student->grade->name
In Model
class student extends Model
{
protected $fillable = ['first_name', 'middle_name', 'last_name', 'grade_id'];
public function grade()
{
return $this->belongsTo('Grade');
}
}
In Controller
$students = Student::with('grade')->get();
In View
#foreach ($students as $student)
$studentGradeName = $student->grade->name;
#endforeach

Categories