Laravel Eloquent With() With() - laravel

How do I go about using multiple Eloquent With()'s?
PortalPlaylistElement Model
class PortalPlaylistElement extends Model
{
public $primaryKey = 'code';
public $incrementing = false;
public $timestamps = false;
public function AirtimePlaylists()
{
return $this->hasOne('App\AirtimePlaylist','id','playlist_id');
}
}
AirtimePlaylistContent Model
class AirtimePlaylistContent extends Model
{
protected $table = 'cc_playlistcontents';
}
AirtimePlaylistModel
class AirtimePlaylist extends Model
{
protected $table = 'cc_playlist';
public function PortalPlaylistElements()
{
return $this->belongsTo('App\PortalPlaylistElement','playlist_id');
}
public function AirtimePlaylistContents()
{
return $this->hasMany('App\AirtimePlaylistContent','playlist_id');
}
}
I have no problems with:
AirtimePlaylist::with('AirtimePlaylistContents')->get());
or
PortalPlaylistElement::with('AirtimePlaylists')->get();
But I'd like to get all AirtimePlaylistContents, in an AirtimePlaylist that belongs to a PortalPlaylistElement.
In essence, (Pseudo code)
PortalPlaylistElement::with('AirtimePlaylists')::with('AirtimePlaylistContents')->get();

You need Nested Eager Looading
PortalPlaylistElement::with('AirtimePlaylists.AirtimePlaylistContents')->get();

nested relations
with('relation1.relation2.relation3')->get(); // relation1 has relation2 relation2 has relation 3
not nested relations
with('relation1','relation2','relation3')->get(); // you model has all relations

I would like to add this if someone needed it
with(['relation1.relation2-1','relation1.relation2-2'])->get(); // relation1 has relation2-1 and relation1 also has relation2-2

Related

Laravel 5.6.17 Model hasOne over multiple tables

I'm quite new to Laravel and now I'm trying to move parts of a former application from a small self written framework into Laravel. The address book is multilingual therefor the table structure is a little more complicated.
db-structure
And this is my source code:
AddressBookController.php
namespace App\Http\Controllers;
use App\AddressBook as AB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class AddressBookController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$entries = AB::all();
return view('addressBook')->with([
'class' => __CLASS__,
'function' => __FUNCTION__,
'line' => __LINE__,
'entries' => $entries,
]);
}
}
Model AddressBook.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class AddressBook extends Model
{
protected $table = 'address';
protected $primaryKey = 'address_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
protected $searchable = [
'columns' => [
'address.address_surname' => 10,
'address.address_company' => 5,
'address.address_vatid' => 2,
],
];
public function country() {
return $this->hasOne('country', 'country_id', 'country_id');
}
public function addresstype() {
return $this->hasOne('addresstype', 'addresstype_id', 'addresstype_id');
}
}
Model Country.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
protected $table = 'country';
protected $primaryKey = 'country_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
public function translation() {
return $this->hasOne('translations', 'translations_id', 'translations_id');
}
public function addressbook() {
return $this->belongsTo('address', 'country_id', 'country_id');
}
}
Model AddressType
namespace App;
use Illuminate\Database\Eloquent\Model;
class AddressType extends Model
{
protected $table = 'addresstype';
protected $primaryKey = 'addresstype_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
public function translation() {
return $this->hasOne('translations', 'translations_id', 'translations_id');
}
public function addressbook() {
return $this->belongsTo('address', 'addresstype_id', 'addresstype_id');
}
}
Model Translation.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Translation extends Model
{
protected $table = 'translations';
protected $primaryKey = 'translations_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
public function country() {
return $this->belongsTo('country', 'translations_id', 'translations_id');
}
public function addresstype() {
return $this->belongsTo('addresstype', 'translations_id', 'translations_id');
}
}
The request "$entries = AB::all();" works in general but I get the id's and maybe I'm completely wrong here but I thought that data from foreign keys will be replaced with the respective models (if configured correctly). so my question is:
a. did I make a mistake during configuration and if yes, where exactly is the error?
or
b. is my assumption of replacing id's with objects is completly wrong?
Thanks in advance!
Steve
Laravel Eloquent models do not replace the foreign keys of the active records with the relational data, it only appends a new property with the same name as the method relating the classes and in that property it puts all the Model instances of the resulted query, this ONLY if you access the property, its called Eager Loading.
It is explained here (Ofiicial Documentation)
$addressBook = App\AddressBook::find(1); //this only will return the active record with the id 1 and nothig more.
$addressBook->country; // The property "country" does not exist in the AddressBook Classs but eloquent models will return a "fake" property with the value of the result of the query by the method with the same name (only if the method returns an Eloquent Relation).
This Eloquent behavior is natural, and is a very clever way to minimize the number of queries, Eloquent will never load a relation if there is no need to.
If you want to load a relation in a set the models at the same time that those models are retriving from the db you need to explicitly especify wich relations you want to load.
$addressBook = App\AddressBook::with(['country', 'addresstype', 'anotherRelation'])->get(); // this will retrive all the addressBook models and in each one will attach the relations specified.
[EDITED]
Also you have to place the entire namespace of the related model class in the relation methods so you need to replaced like:
class Translation extends Model
{
protected $table = 'translations';
protected $primaryKey = 'translations_id';
protected $keyType = 'int';
public $incrementing = true;
public $timestamps = false;
// ****** You need to put the entire namespace of the Model class
public function country() {
return $this->belongsTo('App\Country', 'translations_id', 'translations_id');
}

Call to undefined relationship on model

We have the following class using $with:
class CargaHorasEmpleado extends Model
{
protected $table = "empleados_horas";
protected $with = ["tipoTarea", "proyecto", "empleado", "empleadoQueHizoLaCarga"];
public function tipoTarea()
{
return $this->belongsTo('App\TipoTarea', 'id_tipo_tarea', 'id')->withTrashed();
}
public function empleado()
{
return $this->belongsTo('App\Empleado', 'id_empleado', 'id')->withTrashed();
}
public function empleadoQueHizoLaCarga()
{
return $this->belongsTo('App\Empleado', 'id_empleado_cargo_hs', 'id')->withTrashed();
}
public function proyecto()
{
return $this->belongsTo('App\Proyecto', 'id_proyecto', 'id')->withTrashed();
}
}
This is the class TipoTarea
namespace App;
use Illuminate\Database\Eloquent\Model;
class TipoTarea extends Model
{
protected $table = 'tipos_tareas';
public $timestamps = false;
protected $fillable = [
'titulo', 'descripcion'
];
}
Thep page throws the error: "Call to undefined relationship [tipoTarea] on model [App\CargaHorasEmpleado]". That's the only relationship that's not working. The others are fine. What's wrong?
Well, isn't the relationship called "tipoTarea"? You wrote "tiposTarea"
The problem was that my class "TipoTarea" didn't use softdeletes. So the error was in using the "WithTrashed" method. The correct way is:
public function tipoTarea()
{
return $this->belongsTo('App\TipoTarea', 'id_tipo_tarea', 'id');
}

can't access morphOne relationship

I am having a problem accessing morphOne relationship
In my controller I have
$post = Post::with('content')->where('id', 1)->get();
dd($post);
this gives
This is setup of my classes:
Post.php
class Post extends Model
{
use Contentable;
Contentable.php
trait Contentable {
public function content()
{
return $this->morphOne(Content::class, 'contentable');
}
Content.php
class Content extends Model
{
protected $table = 'content';
public $timestamps = false;
}
If in controller I do this:
dd($post->content());
I get Method content does not exist.
or
dd($post->content);
I get Property [content] does not exist on this collection instance.

How to Bind A model data to all of child Models in Laravel

I have a model for custom fields,I want to bind the configuration detail for all model extended by Base model!
my CoctomFormBulder Model
class CustomFormBuilder extends \Eloquent
{
protected $fillable = [];
protected $table = 'custom_fields_configure';
}
Here is My base model and what I have try up to now.
class BaseModel extends \Eloquent {
protected $guarded = array('q');
protected $table = 'custom_fields_configure';
protected $appends = ['configure'];
public function getConfigerAttribute() {
if (isset($this->attributes['configure'])) {
//return URL::asset($this->attributes['image']);
return $this->attributes['configure'];
}
return '';
}
public function setConfigerAttribute($configure) {
$this->attributes['configure'] = $configure;
}
}
How can Bind Data from CustomFormBuilder to all of my models in the app
Just let the models that need that logic extends the 'CustomFormBuilder' class

How can I select linked objects from multiple parent objects in Laravel Eloquent

I would like to do something like this.
Location::where('city', '=', 'Chicago')->chef();
With these relationships:
class Location extends Eloquent {
protected $table = 'locations';
public function chef() {
return $this->belongsTo('Chef');
}
}
class Chef extends Eloquent {
protected $table = 'chefs';
public function location() {
return $this->hasMany('Location');
}
}
This should work:
class Location extends Eloquent {
protected $table = 'locations';
public function chefs() {
return $this->belongsTo('Chef');
}
public function getAllChefsByCity($city)
{
$this->with('chefs')->where('city', $city)->get();
}
}
Then in your code:
$array = $location->getAllChefsByCity('Chicago');

Resources