Laravel Relation returning null result - laravel-5
My Laravel relation is returning a null result. Can anyone help what i am doing wrong.
Model code is :
public function title()
{
$branch_id=session()->get('lbranch','0');
return $this->hasOne('App\Accounts','code','supp_code')
->select('title')->where('branchid','=',$branch_id);
}
and Controller code is :
$data = Purchase::with('title')
->where('purchases.branchid',$branch_id)
->select('purchases.*',
DB::raw('(CASE
WHEN purchases.posted = "1" THEN "Posted"
ELSE "Unposted"
END) AS status'))
->latest()->get();
the queries generated are :
select `purchases`.*, (CASE
WHEN purchases.posted = "1" THEN "Posted"
ELSE "Unposted"
END) AS status from `purchases`
where `purchases`.`branchid` = 22 order by `created_at` desc
select `title` from `accounts` where `branchid` = 22 and `accounts`.`code` in (100)
UPDATE :
If I use join, the following query is working fine :
$data = DB::table('purchases')
->where('purchases.branchid',$branch_id)
->where('accounts.branchid',$branch_id)
->leftjoin('accounts','purchases.supp_code','=','accounts.code')
->select('purchases.*',
DB::raw('(CASE
WHEN purchases.posted = "1" THEN "Posted"
ELSE "Unposted"
END) AS status'),
'accounts.title')
->latest()->get();
It seems you have issue in your relationship definition. Please do confirm the Model name for the account. It should be Account instead of Accounts. But still you should confirm in your application.
public function title()
{
---
return $this->hasOne('App\Accounts','code','supp_code')
---;
}
Should be
public function title()
{
---
return $this->hasOne('App\Account','code','supp_code')
---;
}
However I try to run your code and it working fine for me.
Here is what I have tried.
App\Models\Purchase.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Purchase extends Model
{
/**
* get model table name.
*
* #var string
*/
public $table = "purchases";
public function title()
{
$branch_id=22;
return $this->hasOne('App\Models\Account','code','supp_code')
->select('title')->where('branchid','=',$branch_id);
}
}
App\Models\Account.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Account extends Model
{
/**
* get model table name.
*
* #var string
*/
public $table = "accounts";
}
in route file.
<?php
Route::get('/', function(){
$branch_id = 22;
$data = Purchase::with('title')
->where('purchases.branchid',$branch_id)
->select('purchases.*',
\DB::raw('(CASE
WHEN purchases.posted = "1" THEN "Posted"
ELSE "Unposted"
END) AS status'))
->latest()->get();
dd($data->toArray());
$data = \DB::table('purchases')
->where('purchases.branchid',$branch_id)
->where('accounts.branchid',$branch_id)
->leftjoin('accounts','purchases.supp_code','=','accounts.code')
->select('purchases.*',
\DB::raw('(CASE
WHEN purchases.posted = "1" THEN "Posted"
ELSE "Unposted"
END) AS status'),
'accounts.title')
->latest()->get();
dd($data);
});
Both query working for me. And returning the desire result.
Query1
array:2 [▼
0 => {#436 ▼
+"id": 6
+"refno": 21
+"supp_code": 100
+"total": 41241
+"posted": 1
+"date": "2019-05-25 22:53:00"
+"branchid": 22
+"created_at": "2019-05-25 22:53:00"
+"updated_at": "2019-05-25 22:53:00"
+"status": "Posted"
+"title": "test"
}
1 => {#438 ▼
+"id": 3
+"refno": null
+"supp_code": 100
+"total": 3114
+"posted": null
+"date": "2019-05-25 22:53:00"
+"branchid": 22
+"created_at": "2019-05-25 22:53:00"
+"updated_at": "2019-05-25 22:53:00"
+"status": "Unposted"
+"title": "test"
}
]
Query2
array:2 [▼
0 => {#436 ▼
+"id": 3
+"refno": null
+"supp_code": 100
+"total": 3114
+"posted": null
+"date": "2019-05-25 22:53:00"
+"branchid": 22
+"created_at": "2019-05-25 22:53:00"
+"updated_at": "2019-05-25 22:53:00"
+"status": "Unposted"
+"title": "test"
}
1 => {#438 ▼
+"id": 6
+"refno": 21
+"supp_code": 100
+"total": 41241
+"posted": 1
+"date": "2019-05-25 22:53:00"
+"branchid": 22
+"created_at": "2019-05-25 22:53:00"
+"updated_at": "2019-05-25 22:53:00"
+"status": "Posted"
+"title": "test"
}
]
Database SQL
CREATE TABLE `accounts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`code` int(11) DEFAULT NULL,
`title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`branchid` int(11) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `accounts` VALUES (3,100,'test',22,NULL,NULL),(4,2,'testsetestes',34,NULL,NULL),(5,2,'testest seat',456,NULL,NULL),(6,3,'testse aeta ',22,NULL,NULL);
CREATE TABLE `purchases` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`refno` int(11) DEFAULT NULL,
`supp_code` int(11) DEFAULT NULL,
`total` int(11) DEFAULT NULL,
`posted` int(11) DEFAULT NULL,
`date` timestamp NULL DEFAULT NULL,
`branchid` int(11) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `purchases` VALUES (3,NULL,100,3114,NULL,'2019-05-25 22:53:00',22,'2019-05-25 22:53:00','2019-05-25 22:53:00'),(4,23,101,4324,1,'2019-05-25 22:53:00',23,'2019-05-25 22:53:00','2019-05-25 22:53:00'),(5,22,101,32424,0,'2019-05-25 22:53:00',21,'2019-05-25 22:53:00','2019-05-25 22:53:00'),(6,21,100,41241,1,'2019-05-25 22:53:00',22,'2019-05-25 22:53:00','2019-05-25 22:53:00');
Edits:
Tryied running your code.. here is the changes suggested.
PurchaseController
public function index()
{
//
$branch_id = 22;
$data = Purchase::with('account')
->where('purchases.branchid',$branch_id)
->select('purchases.*',
\DB::raw('(CASE
WHEN purchases.posted = "1" THEN "Posted"
ELSE "Unposted"
END) AS status'))
->latest()->get();
dd($data->toArray());
/*$data = \DB::table('purchases')
->where('purchases.branchid',$branch_id)
->where('accounts.branchid',$branch_id)
->leftjoin('accounts','purchases.supp_code','=','accounts.code')
->select('purchases.*',
\DB::raw('(CASE
WHEN purchases.posted = "1" THEN "Posted"
ELSE "Unposted"
END) AS status'),
'accounts.title')
->latest()->get();
dd($data);*/
}
Purchage Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Purchase extends Model
{
//
public $table = "purchases";
public function account()
{
$branch_id=22;
return $this->hasOne('App\Account','code','supp_code')
->where('branchid', $branch_id);
}
}
Result:
array:2 [▼
0 => array:11 [▼
"id" => 3
"refno" => 24
"supp_code" => 100
"total" => 3114
"posted" => null
"date" => "2019-05-25 22:53:00"
"branchid" => 22
"created_at" => "2019-05-25 22:53:00"
"updated_at" => "2019-05-25 22:53:00"
"status" => "Unposted"
"account" => array:6 [▼
"id" => 3
"code" => 100
"title" => "test"
"branchid" => 22
"created_at" => null
"updated_at" => null
]
]
1 => array:11 [▼
"id" => 6
"refno" => 21
"supp_code" => 100
"total" => 41241
"posted" => 1
"date" => "2019-05-25 22:53:00"
"branchid" => 22
"created_at" => "2019-05-25 22:53:00"
"updated_at" => "2019-05-25 22:53:00"
"status" => "Posted"
"account" => array:6 [▼
"id" => 3
"code" => 100
"title" => "test"
"branchid" => 22
"created_at" => null
"updated_at" => null
]
]
]
Related
Laravel belongsto relations get property problem
I have belongsto relation: class Yetkiliservis extends Model { protected $table = 'yetkiliservis'; protected $guarded=[]; public function bolge(){ return $this->belongsTo(Bolgeler::class); } } when I convert the model to array everything is right. It shows relation. $yetkiliservisler = Yetkiliservis::with('bolge')->get(); dd($yetkiliservisler[0]->toArray()); result : array:22 [▼ "id" => 1 "vergi_no" => "1" "yerel_adi" => "1" "bolge" => array:6 [▼ <------------------------------------ "id" => 1 "bolge_adi" => "İSTANBUL" "ad_soyad" => "istanbul" "email" => "istanbul#mail.com" "created_at" => "2020-04-24 15:53:31" "updated_at" => "2020-04-24 15:53:31" ] "yetkili_adi" => "1" ] But when I try to get by the property it shows null. $yetkiliservisler = Yetkiliservis::with('bolge')->get(); dd($yetkiliservisler[0]->getAttributes()); result : array:22 [▼ "id" => 1 "vergi_no" => "1" "yerel_adi" => "1" "bolge" => null <-------------------------------- "yetkili_adi" => "1" ]
First you change the raname like this public function bolges(){ return $this->hasMany(Bolge::class,'yetkiliservi_id','id'); } After you execute this command composer dump-autoload Then first check php artisan tinker; relation is correct?? Then try this $yetkiliservisler[0]->bolges; Hope it will helpful for you
use sync method for an array and also add extra pivot fields?
This is my input array "events" => array:2 [▼ "special-date" => array:3 [▼ 0 => "14-Nov-1979" 1 => "18-Apr-1981" 2 => "12-Nov-1978" ] "event" => array:3 [▼ 0 => "2" 1 => "3" 2 => "4" ] ] This is my code $User->events()->sync($request->events['event'], ['event_date' => $request->events['special-date']]); here, $user is an instance of the user model This is my user model realtion function public function events() { return $this->belongsToMany('App\Models\Event', 'user_events', 'user_id', 'event_id')->withPivot('event_date'); } and I got an error of event_date has no default value. my table structure of a user_event table is id, user_id, event_id, event_date
Access pivotParent in Laravel
I have 3 tables : langs : id (PK) , langname lang_sector : lang_id (FK) , sector_id (FK) , sectorname .... sectors : id (PK) Here are the relations in Lang model public function sectors(){ return $this->belongsToMany('App\Sector') ->withPivot('sectname','sectshortname','sectdescription','sectshortdescription') ->whereNull('lang_sector.deleted_at') ->withTimestamps(); } Here are the relations in Sector model public function langs(){ return $this->belongsToMany('App\Lang') ->withPivot('sectname','sectshortname','sectdescription','sectshortdescription') ->whereNull('lang_sector.deleted_at') ->withTimestamps(); } I create an index method public function index() { $countLang = Lang::count(); $countSector = Sector::count(); $admins = Admin::all(); for ($i=1; $i<=$countLang; $i++) { $langs = Lang::find($i); $sectors[$i] = $langs->sectors()->get(); } return view('admin.sectors.index', compact('admins', 'sectors', 'langs', 'countLang', 'countSector')); } In my front I have to reach for each sector, the langname which is in the lang table ... When I use the dd() method in the view #foreach ($sectors as $sector) #for($i=0; $i < $countSector; $i++) {{ dd($sector[$i]->pivot) }} #endfor #endforeach I obtain those result (abstract) : Pivot {#684 ▼ +pivotParent: Lang {#636 ▼ #table: "langs" #fillable: array:2 [▼ 0 => "langname" 1 => "langisocode" ] .... #attributes: array:6 [▼ "id" => 1 "langname" => "Français" "langisocode" => "fr-FR" "created_at" => "2018-02-06 08:19:24" "updated_at" => "2018-02-07 18:56:21" "deleted_at" => null ... ] #original: array:6 [▼ "id" => 1 "langname" => "Français" ... ] .... } #foreignKey: "lang_id" #relatedKey: "sector_id" #table: "lang_sector" #primaryKey: "id" .... #attributes: array:8 [▼ "lang_id" => 1 "sector_id" => 1 "sectname" => "Technologies de l'information et de la Communication" "sectshortname" => "TIC" "sectdescription" => "description TIC" "sectshortdescription" => "description TIC courte" "created_at" => "2018-02-07 21:41:10" "updated_at" => "2018-02-07 21:41:10" ] .... } It means that i can surelly reach the langs table and its columns... The question is "how can i do it" ... Thanks for your answer
I see a logic problem When the ids are continuously, it will work well +-----+------------+ | id | langname | | 1 | esp | | 2 | esp2 | | 3 | esp3 | +-----+------------+ $ countLang = Lang :: count (); //3 The for route from 1 to 3 for ($i=1; $i<=$countLang; $i++) { $langs = Lang::find($i); $sectors[$i] = $langs->sectors()->get(); } Here is the error, look at the id's $countLang = Lang :: count (); //3 +-----+------------+ | id | langname | | 1 | esp | | 3 | esp2 | | 4 | esp3 | +-----+------------+ The for will never arrive at id = 4, because in the Lang::count(); is 3 Lang :: find (1) ok Lang :: find (2) error Lang :: find (3) ok Read the documentation https://laravel.com/docs/5.5/eloquent-relationships
You could use $sector->pivot->fieldName;
Finally i rewrote my sql request ... What i want to diplay is the result of this request : SELECT sectors.*, lang_sector.*, langs.* FROM sectors INNER JOIN lang_sector ON sectors.id = lang_sector.sector_id INNER JOIN langs ON lang_sector.lang_id = langs.id; So i decided to use query builder : $sectors = DB::table('sectors') ->join('lang_sector','sectors.id','=','lang_sector.sector_id') ->join('langs','lang_sector.lang_id','=','langs.id') ->select('langs.*', 'lang_sector.*', 'sectors.*') ->get(); Then in my view i don't have to use any pivot stuff and just have to write this way : #foreach($sectors as $sector) {{ $sector->anyfieldfromrequest }} #endforeach Thanks for your answers... Mainly Samuel Loza who shows me the problems encountered by my first request
Eloquent $appends acts strangely in laravel 5.3
am simply trying to include a new attribute to be available in the json response but for some reason am also getting the object relation as well. // user model protected $guarded = ['id']; protected $appends = ['role_name']; protected $hidden = ['remember_token', 'password']; public function getRoleNameAttribute() { return $this->role->type; } public function role() { return $this->belongsTo(Role::class); } // role model public function users() { return $this->hasMany(User::class); } when i use dd($user); i get User {#303 #guarded: array:1 [ 0 => "id" ] #appends: array:1 [ 0 => "role_name" ] #hidden: array:2 [ 0 => "remember_token" 1 => "password" ] #connection: null #table: null #primaryKey: "id" #keyType: "int" #perPage: 15 +incrementing: true +timestamps: true #attributes: array:7 [ "name" => "testing" "email" => "email#asd.com" "password" => "$2y$10$fogQXhJZm5eoViM38pge1.BmNxY7IFl515zT83.Ks9Uj26kK9T6Im" "role_id" => "83eee2e0-8939-48f7-9fbc-1c077e2265e5" "id" => "a181fb4b-b65a-47b4-9c72-21ea15c6c5a6" "updated_at" => "2017-01-30 20:23:52" "created_at" => "2017-01-30 20:23:52" ] #original: array:7 [ "name" => "testing" "email" => "email#asd.com" "password" => "$2y$10$fogQXhJZm5eoViM38pge1.BmNxY7IFl515zT83.Ks9Uj26kK9T6Im" "role_id" => "83eee2e0-8939-48f7-9fbc-1c077e2265e5" "id" => "a181fb4b-b65a-47b4-9c72-21ea15c6c5a6" "updated_at" => "2017-01-30 20:23:52" "created_at" => "2017-01-30 20:23:52" ] ... } and with return response()->json(compact('user')); instead i get user: { created_at: "2017-01-30 20:26:12" email:"email#asd.com" id:"4b83e031-e8c8-4050-963d-446cb383fb14" name:"testing" role:{ created_at:"2016-12-29 10:54:02" id:"83eee2e0-8939-48f7-9fbc-1c077e2265e5" type:"user" updated_at:"2016-12-29 10:54:02" } role_id:"83eee2e0-8939-48f7-9fbc-1c077e2265e5" role_name:"user" updated_at:"2017-01-30 20:26:12" } but what i expect is to only have user: { created_at: "2017-01-30 20:26:12" email:"email#asd.com" id:"4b83e031-e8c8-4050-963d-446cb383fb14" name:"testing" role_id:"83eee2e0-8939-48f7-9fbc-1c077e2265e5" role_name:"user" updated_at:"2017-01-30 20:26:12" } so am not sure if this is the normal behavior or a bug or maybe am missing something ? Laravel version 5.3.30
The reason why this is happening is the following public function getRoleNameAttribute() { return $this->role->type; } The problem here is the when you say $this->role it will automatically attached the relationship to the model. In order to prevent this, you should simply be able to access the method directly, like $this->role(). public function getRoleNameAttribute() { return $this->role()->first()->type; }
CodeIgniter: Unknown column 'xxx' in 'field list'
Here's my exported BD table: CREATE TABLE `hta_users` ( `id` int(11) NOT NULL auto_increment, `nombre` varchar(100) collate utf8_spanish_ci NOT NULL, `apellidos` varchar(255) collate utf8_spanish_ci NOT NULL, `nif` varchar(10) collate utf8_spanish_ci NOT NULL, `direccion` varchar(255) collate utf8_spanish_ci NOT NULL, `cp` varchar(5) collate utf8_spanish_ci NOT NULL, `poblacion` varchar(255) collate utf8_spanish_ci NOT NULL, `provincia` int(2) NOT NULL, `telefono` varchar(9) collate utf8_spanish_ci NOT NULL, `edad` int(3) NOT NULL, `retribucion` int(1) NOT NULL, `entidad` varchar(4) collate utf8_spanish_ci NOT NULL, `oficina` varchar(4) collate utf8_spanish_ci NOT NULL, `dc` varchar(2) collate utf8_spanish_ci NOT NULL, `cc` varchar(10) collate utf8_spanish_ci NOT NULL, `centro` varchar(255) collate utf8_spanish_ci NOT NULL, `email` varchar(255) collate utf8_spanish_ci NOT NULL, `especialidad` int(2) NOT NULL, `parent` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `nif` (`nif`,`email`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=1 ; Here's my model function: function add_user( $nombre, $apellidos, $nif, $direccion, $cp, $poblacion, $provincia, $telefono, $edad, $retribucion, $cc_entidad, $cc_oficina, $cc_dc, $cc_cc, $centro, $email, $especialidad, $parent ) { $tbl = $this->db->dbprefix('users'); if( $retribucion == 1 ) { $sql = array( 'nombre' => $nombre, 'apellidos' => $apellidos, 'nif' => $nif, 'direccion' => $this->db->escape($direccion), 'cp' => $cp, 'poblacion' => $poblacion, 'provincia' => $provincia, 'telefono' => $telefono, 'edad' => $edad, 'retribucion' => $retribucion, 'entidad' => $cc_entidad, 'oficina' => $cc_oficina, 'dc' => $cc_dc, 'cc' => $cc_cc, 'centro' => $centro, 'email' => $email, 'especialidad' => $especialidad, 'parent' => $parent ); } else { $sql = array( 'nombre' => $nombre, 'apellidos' => $apellidos, 'nif' => $nif, 'direccion' => $this->db->escape($direccion), 'cp' => $cp, 'poblacion' => $poblacion, 'provincia' => $provincia, 'telefono' => $telefono, 'edad' => $edad, 'retribucion' => $retribucion, 'centro' => $centro, 'email' => $email, 'especialidad' => $especialidad, 'parent' => $parent ); } $this->db->insert($tbl, $sql); if( $this->db->affected_rows() == 0 ) return false; else return true; } Here's my controller piece of code: if( $this->users->add_user($nombre, $apellidos, $nif, $direccion, $cp, $poblacion, $provincia, $telefono, $edad, $retribucion, $cc_entidad, $cc_oficina, $cc_dc, $cc_cc, $centro, $email, $especialidad, $parent) ) { $data['form_error'] = 'Se ha añadido al usuario.'; $data['module'] = 'registro'; $this->load->view('template', $data); } else { $data['form_error'] = 'Se ha producido un error al agregar al usuario a la BD.'; $data['module'] = 'registro'; $this->load->view('template', $data); } And that's the error i'm getting: A Database Error Occurred Error Number: 1054 Unknown column 'entidad' in 'field list' INSERT INTO `hta_users` (`nombre`, `apellidos`, `nif`, `direccion`, `cp`, `poblacion`, `provincia`, `telefono`, `edad`, `retribucion`, `entidad`, `oficina`, `dc`, `cc`, `centro`, `email`, `especialidad`, `parent`) VALUES ('nombre', 'apellidos', '12345678Q', '\'elm st 666\'', '08008', 'Barcelona', '1', '666555666', '2', 1, '9999', '9999', '99', '9999999999', 'home', 'email#domain.com', '1', '0') Can someone help? I don't know what's happening nor why... :/
Here is an article I wrote that will help you with debugging CodeIgniter ActiveRecord. Basically use $this->db->last_query() to see what ActiveRecord built your query to be and run it in phpMyAdmin to see if the query itself is valid. There are a few other tips too, but from what I can see here everything looks fine. Sneaky tip: you can use: return !$this->db->affected_rows() == 0; instead of: if( $this->db->affected_rows() == 0 ) return false; else return true;
Well, after some hours of harddebuggin' got it working... :P Same database table structure. My new model function: function add_user( $user_data ) { $tbl = $this->db->dbprefix('users'); $this->db->insert($tbl, $user_data); return !$this->db->affected_rows() == 0; } My new controller piece of code: $user_data = array( 'nombre' => $this->input->post('nombre'), 'apellidos' => $this->input->post('apellidos'), 'nif' => $this->input->post('nif'), 'direccion' => $this->db->escape($this->input->post('direccion')), 'cp' => $this->input->post('cp'), 'poblacion' => $this->input->post('poblacion'), 'provincia' => $this->input->post('provincia'), 'telefono' => $this->input->post('telefono'), 'edad' => $this->input->post('edad'), 'retribucion' => $this->input->post('retribucion'), 'entidad' => $this->input->post('cc_entidad'), 'oficina' => $this->input->post('cc_oficina'), 'dc' => $this->input->post('cc_dc'), 'cc' => $this->input->post('cc_cc'), 'centro' => $this->input->post('centro'), 'email' => $this->input->post('email'), 'especialidad' => $this->input->post('especialidad'), 'parent' => $this->session->userdata('parent') ); // db adding if( $this->users->add_user($user_data) ) { // logged in!! } else { // grrr error!! } It looks much pretty now! :) Hope this helps some lost souls to DO NOT construct the AR data array into the model, but the controller.