I am trying to chain 3 models together parent->child->child of child. So I can access it in an eloquent statement.
Parent Model:
class CertificationType extends Model
{
use SoftDeletes;
public $timestamps = true;
protected $table = 'certification_type';
protected $dates = ['deleted_at'];
protected $fillable = array('certification_type_name', 'fa_code', 'icon_image');
protected $hidden = ['created_at', 'updated_at',];
public function certification_type()
{
return $this->hasMany('App\Certification');
}
}
Child Model
class Certification extends Model
{
protected $table = 'certification';
public $timestamps = true;
use SoftDeletes;
protected $dates = ['deleted_at'];
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = array('certification_type_id', 'certification_name', 'certication_date', 'certification_license_number', 'certification_course_length', 'certification_course_description', 'certification_course_topics_list_id');
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'created_at', 'updated_at',
];
public function certification_type()
{
return $this->belongsTo('App\CertificationType',
'certification_type_id');
}
public function certification_course_topics_list()
{
return $this->hasMany('App\CertificationCourseTopicsList');
}
}
Child of Child Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class CertificationCourseTopicsList extends Model
{
protected $table = 'certification_topics_list';
public $timestamps = true;
use SoftDeletes;
protected $dates = ['deleted_at'];
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = array('certification_id', 'certification_topic_description');
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'created_at', 'updated_at',
];
public function certification_course_topics_list()
{
return $this->belongsToMany('App\Certification', 'certification_id');
}
}
The eloquent statement I am using is:
$CertificationTypes = App\CertificationType::orderBy('id',"asc")->with('certification_type')->get()->groupBy('id');
What I have accomplished is CertificationType has a child of Certifications attached in the query. What I need is the 2nd child to be in the query as well:
CertificationType::orderBy('id',"asc")->with('certification_type')->get()->groupBy('id')->with('certification')->get()->groupBy('id');
I also tried:
CertificationType::orderBy('id',"asc")->with('certification_type, certifications')->get()->groupBy('id');
That did not work: Call to undefined relationship [certification_type, certifications] on model [App\CertificationType].
Also tried:
CertificationType::orderBy('id',"asc")->with('certification_type', 'certifications')->get()->groupBy('id');
That did not work: Call to undefined relationship [certifications] on model [App\CertificationType].
Any help would be appreciated!
You need more order in code. I would make three models with proper relations as : belongsTo and hasMany. Then in each view you can use data from model with function of relation.
Example of proper model with relation:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* Get the comments for the blog post.
*/
public function comments()
{
return $this->hasMany('App\Comment');
}
}
Read more here, that will save your time: https://laravel.com/docs/5.5/eloquent-relationships#one-to-many
Related
I am trying to convert the below DB query to an eloquent relation.
$device_barcodes = ["BSC0337", "BSC0503", "BSC0626"];
$devices = DB::table('devices')
->leftjoin('devices_repairs', 'devices_repairs.device_id', '=', 'devices.device_id')
->leftJoin('staff','staff.staff_id','devices_repairs.repair_damaged_by')
->whereIn('barcode', $device_barcodes)
->get();
So far I have the below, but I am struggling with the staff relation.
$devices = Devices::with('repairDetails')->whereIn('barcode', $device_barcodes)->get();
I've overcome this for now with the below, but this is not ideal.
foreach($devices as $device) {
$staff_name = Staff::find($device->repairDetails->repair_damaged_by);
$device->staff_name = $staff_name->staff_name;
}
I am hoping for something like:
$devices = Devices::with('repairDetails')->with('staffDetails')->whereIn('barcode', $device_barcodes)->get();
This way I can show the device details, the repair details and the staff name on my blade form.
So the basic issue is I am trying to relate three models together.
Devices is the top model, where I join with DevicesRepairs using the device_id primary and foreign keys. But for the Staff model I need to join devices_repairs.repair_damaged by to staff.staff_id.
Here are my models:
Devices:
class Devices extends Model
{
/**
* #var bool $timestamps Disable timestamps
*/
public $timestamps = false;
/**
* #var string $table Name of the db table
*/
protected $table = 'devices';
/**
* #var string $primaryKey Name of the primary key
*/
protected $primaryKey = 'device_id';
/**
* #var array $fillable The attributes that are mass assignable.
*/
protected $fillable = [
'status',
'order_reference',
'model',
'serial',
'imei',
'barcode',
'mobile_number',
'helpdesk_url_id',
'device_notes'
];
use Searchable;
function repairDetails() {
return $this->hasOne(DevicesRepairs::class, 'device_id');
}
function repairHistoryDetails() {
return $this->hasOne(DevicesRepairsHistory::class, 'device_id');
}
}
DevicesRepairs:
class DevicesRepairs extends Model
{
use HasFactory;
protected $table = 'devices_repairs';
protected $primaryKey = 'device_id';
public $timestamps = false;
protected $fillable = [
'device_id',
'repair_damanged_by',
'repair_damage_type',
'repair_date_received',
'repair_date_sent_for',
'repair_damage_notes',
'repairer_name',
'repair_is_user_damage',
'job_number',
'operator_date_received',
'operator_date_received_by',
'operator_date_sent',
'operator_sent_by',
'photo_id',
'photo_id_back'
];
function device() {
return $this->hasOne(Devices::class, 'device_id');
}
//This doesn't work - seems to return a random staff member.
function staffDetails() {
return $this->hasOne(Staff::class,'staff_id','repair_damaged_by');
}
}
Staff:
class Staff extends Model
{
use searchable;
/**
* #var bool $timestamps Disable timestamps
*/
public $timestamps = false;
/**
* #var string $table Name of the db table
*/
protected $table = 'staff';
/**
* #var string $primaryKey Name of the primary key
*/
protected $primaryKey = 'staff_id';
/**
* #var array $fillable The attributes that are mass assignable.
*/
protected $fillable = [
'staff_id',
'staff_name',
'manager_id',
'is_active',
'is_mdm_user',
'user_id',
];
}
My ultimate aim is to be able to return fields like this in my view:
{{$device->barcode}}
{{$device->repairDetails->repair_damage_notes}}
//The above work fine but not this:
{{$device->staffDetails->staff_name}}
treat at as a pivot table, a many to many relation between devices and staff
class Devices extends Model
{
public function damagedBy()
{
return $this->belongsToMany(Staff::class, 'devices_repairs', 'device_id', 'repair_damaged_by');
}
So the query will be like
$device_barcodes = ["BSC0337", "BSC0503", "BSC0626"];
$devices = Devices::with('damagedBy')->whereIn('barcode', $device_barcodes)->get();
I have the following code:
$model = new coretable;
log::info($model->all());
$model = $model->makeVisible('id_coretable');
log::info($model->all());
In my lumen log, I get the following result:
[2020-02-26 10:14:19] local.INFO: [{"Internal_key":"TESTKEY_1"},{"Internal_key":"TESTKEY_2"},{"Internal_key":"TESTKEY_3"},{"Internal_key":"TESTKEY_4"},{"Internal_key":"TESTKEY_5"}]
[2020-02-26 10:14:19] local.INFO: [{"Internal_key":"TESTKEY_1"},{"Internal_key":"TESTKEY_2"},{"Internal_key":"TESTKEY_3"},{"Internal_key":"TESTKEY_4"},{"Internal_key":"TESTKEY_5"}]
I would expect the "id_coretable" attribute to be present in the second output from log::info(), but it isnt.
Why is that?
Here is the model of coretable:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class CoreTable extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'coretable';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'Internal_key'
];
protected $hidden = [
'id_coretable',
'created_at',
'updated_at'
];
protected $primaryKey = 'id_coretable';
/**
* Many-To-Many relationship with User-Model.
*/
public function extensiontable_itc()
{
return $this->hasOne('App\extensiontable_itc', 'coretable_id');
}
public function extensiontable_sysops()
{
return $this->hasOne('App\extensiontable_sysops', 'coretable_id');
}
public function inaccessibletable()
{
return $this->hasOne('App\inaccessibletable', 'coretable_id');
}
}
I have no clue why makeVisible() doesnt have any effect on the effect.
The initial model you created does not have any influence on the models received from the all() function. This is a collection of new models with the initial $hidden array.
To change what values are shown, you will have to call makeVisible on the collection you receive:
$model = new coretable;
log::info($model->all());
log::info($model->all()->makeVisible('id_coretable'));
It is also recommended to call the query functions staticaly, this way you don't need to create an initial model:
log::info(coretable::all()->makeVisible('id_coretable'));
I have created a relationship between User model and StoryModel. But it give me the Error:-
Call to undefined relationship [userStories] on model [App\User].
May be I'm missing something. Following is my code which I'm using
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Notification;
use App\CheckIn;
use App\Travel;
use Carbon\Carbon;
use App\NewInterest;
use App\UserStory;
class User extends Authenticatable
{
use Notifiable;
protected $table = "users";
protected $primaryKey = 'id';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'firstname','lastname', 'user_id','email',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function userStories(){
return $this->hasMany(UserStory::class, 'user_id', 'user_id');
}
}
Controller Logic
$usersStories = User::with('userStories')
->select('id','user_id','stories')
->get();
print_r($usersStories);
exit;
Are you wriiten mapping code in your UserStory Model that should be
public function userAccount(){
return $this->belongsTo(User::class);
}
If you already written this code then check you column names in your DB.
Can you try by changing the sequence like this:
$usersStories = User::->select('id','user_id','stories')
->with('userStories')
->get();
print_r($usersStories);
exit;
You should update your model and try:
User model
public function userStories(){
return $this->hasMany(UserStory::class);
}
UserStory model
public function users(){
return $this->belongsTo(User::class, 'user_id');
}
I have two tables
1.
Game Console
-- console_id
-- console_name
2.
Game Labels
-- game_label_id
-- console_id (foreign key)
-- title
-- description
-- image
-- created
GameConsole Model
namespace App\Http\Models;
use Illuminate\Database\Eloquent\Model;
class GameConsole extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
public $timestamps = false;
protected $table = 'console';
protected $fillable = array('console_name', 'description', 'created');
protected $primaryKey = 'console_id';
public function labels()
{
return $this->hasMany('App\Http\Models\GameLabel','console_id');
}
}
GameLabel Model
namespace App\Http\Models;
use Illuminate\Database\Eloquent\Model;
class GameLabel extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
public $timestamps = false;
protected $table = 'game_label';
protected $fillable = array('game_label_id','console_id', 'title','description','image', 'release_date','status','created');
protected $primaryKey = 'game_label_id';
public function console()
{
return $this->belongsTo('App\Http\Models\GameConsole','console_id');
}
}
I write this query to get all game labels with console_name
GameLabel::with('console')->get();
But I am only getting records from game_label table, not from console table.
Can any body please tell me that what query I have to write to get all records?
Please don't suggest me about query builder joins. I don't want to use that.
namespace App\Http\Models;
use Illuminate\Database\Eloquent\Model;
class GameLabel extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
public $timestamps = false;
protected $table = 'game_label';
protected $fillable = array('game_label_id','console_id', 'title','description','image', 'release_date','status','created');
protected $primaryKey = 'game_label_id';
public function console()
{
return $this->belongsTo('App\Http\Models\GameConsole', 'console_id', 'console_id');
}
}
in belongs to first console_id represent Game Console table id and and second console_id represent game_label table console_id
now in controller
GameLabel::with('console')->get();
i think all data will be availbale in array under console key
Yes, its under console key. I found the solution.
the console name was not getting in the view so get the console name in view like this
foreach($game_label as $getGameLabel){
echo $getGameLabel->console->console_name;
}
I am trying to do the following:
$org = Organization::first();
$user = Auth::user();
$org->owner()->save($user);
return $org;
My returned values are:
{"_id":"55f333759a370912040041c8",
"name":"Beta Productions",
"updated_at":"2015-09-11 20:03:01",
"created_at":"2015-09-11 20:03:01"}
If I try to return $org->owner, I don't get anything.
Here is my organization class:
<?php
namespace App;
use Jenssegers\Mongodb\Model as Model;
class Organization extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['name'];
public function owner()
{
return $this->embedsOne('App\User');
}
}
Any thoughts?