hasManyThrough returning empty array - php

I need some help with my hasManyThrough relationship
I have 3 tables:
Field Table
id
Submission Field Table
id
field_id
Submission Field Values Table
id
submission_field_id
and I'm trying to get all the SubmissionFieldValue for the Field through SubmissionField with this:
public function FieldValues() {
return $this->hasManyThrough(SubmissionFieldValues::class, SubmissionField::class, 'id', 'submission_field_id', 'id', 'form_field_id');
}
So my logic is:
Match Field's id to Submission Field's field_id then use those Submission Fields' id to match with Submission Field Value's submission_field_id and return all of those SubmissionFieldValues.
I'm not entirely sure why this doesn't return anything. It's not throwing an error either when I run it so I'm guessing it's just an issue with my key/parameter ordering.
Thank you for any and all help!

The relation you are looking for is:
public function fieldValues() {
return $this->hasManyThrough(SubmissionFieldValues::class,
SubmissionField::class, 'field_id', 'submission_field_id', 'id');
}
And to retrieve the values:
return $object->fieldValues;

Has Many Through
Let's look at the tables required to define this relationship:
countries
id - integer
name - string
users
id - integer
country_id - integer
name - string
posts
id - integer
user_id - integer
title - string
If you would like to customize the keys of the relationship, you may pass them as the third and fourth arguments to the hasManyThrough method. The third argument is the name of the foreign key on the intermediate model. The fourth argument is the name of the foreign key on the final model. The fifth argument is the local key, while the sixth argument is the local key of the intermediate model:
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(
'App\Models\Post',
'App\Models\User',
'country_id', // Foreign key on users table...
'user_id', // Foreign key on posts table...
'id', // Local key on countries table...
'id' // Local key on users table...
);
}
}

Related

Speed up query through laravel relationships

There are 3 models:
First (first_id)
Connection (connection_id, first_id, product_id)
Second (second_id, product_id)
I would like to connect the three models together using laravel relationships
First->joined to Connection though first_id
Connection->joined to First through first_id, & joined to Second through product_id
Second -> joined to Connection through product_id
So: First joined to Second through Connection first_id, product_id
Is this possible to do using something like HasManyThrough?
Thanks for your time
On your First model:
public function second () {
return $this->hasManyThrough(
Second::class,
Connection::class,
'product_id', // Foreign key on connection table
'product_id', // Foreign key on second table
'first_id', // Local key on first table
'first_id' // Local key on connection table
);
}
Based on your description the column names should work.
In tinker you can validate if it's hooked up correctly by doing something like First::first()->second.
It depends on what type of relationship Your first model and second model shares as well as what type of relation second and third model shares.
if consider your first model First and second model Second shares a one-to-one relation, as well as Second model and Third models shares one-to-one relationships.
It will be $first->second->third; //no has many through relationship requires
If your First model and Second models shares as hasMany-belongs to relation than you need to use hasManyThrough relationship
example from doc
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(
'App\Post',
'App\User',
'country_id', // Foreign key on users table...
'user_id', // Foreign key on posts table...
'id', // Local key on countries table...
'id' // Local key on users table...
);
}
}
You can try using nested relationships.
Nested Eager Loading
To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:
$books = App\Book::with('author.contacts')->get();
Book Model:
public function author()
{
return $this->hasOne('App\Author');
}
Author Model:
public function contacts()
{
return $this->hasMany('App\Author');
}
Documentation:
https://laravel.com/docs/5.8/eloquent-relationships

Laravel belongsToMany retrieve more then one row

So im creating a booking system where you can create maps and assign them to an event. I have 3 tables to handle this, events, maps, and event_maps
I have after reading the Laravel Documentation i decided to set up a belongsToMany relation.
But when i try to retrieve my maps thru my event model i only get one the first row.
in my controller i do
public function displayForm($id)
{
$event = EventModel::find($id);
print_r($event->maps);
}
The result is a Illuminate\Database\Eloquent\Collection Object with the last out of 2 maps, and i can't for my life figger out how to get them all.
My EventsModel
public function maps()
{
return $this->belongsToMany('App\Models\Booky\MapsModel',
// Table name of the relationship's joining table.
'event_maps',
// Foreign key name of the model on which you are defining the relationship
'map_id',
// Foreign key name of the model that you are joining to
'event_id'
);
}
My MapsModel
public function event()
{
return $this->belongsToMany('App\Models\Booky\EventsModel',
// Table name of the relationship's joining table.
'event_maps',
// Foreign key name of the model on which you are defining the relationship
'event_id',
// Foreign key name of the model that you are joining to
'map_id'
);
}
The database looks something like this
events
- id
- lots of irrelevant data
maps
- id
- lots of irrelevant data
event_maps
- id
- event_id
- map_id
I was thinking that perhaps i should use another relation type, but as far as i understand they don't use a relation table like event_maps.
Everything else work as expected.
Anyone who could clear up this mess? :)
The ids are inverted in the relation. Try this:
public function maps()
{
return $this->belongsToMany('App\Models\Booky\MapsModel',
// Table name of the relationship's joining table.
'event_maps',
// Foreign key name of the model that you are joining to
'event_id'
// Foreign key name of the model on which you are defining the relationship
'map_id',
);
}
And:
public function event()
{
return $this->belongsToMany('App\Models\Booky\EventsModel',
// Table name of the relationship's joining table.
'event_maps',
// Foreign key name of the model that you are joining to
'map_id'
// Foreign key name of the model on which you are defining the relationship
'event_id',
);
}

Laravel - hasManyThrough return only _id

I use Laravel MongoDB package by jenssegers and Eloquent Laravel Model.
articles :
_id (ObjectID)
feed_id
title
feeds :
id
user_id
name
users :
id
name
hasManyThrough in User::class model to get all articles by one user.
public function articles()
{
return $this->hasManyThrough(
'App\Article',
'App\Feed',
'user_id', // Foreign key on feeds table...
'feed_id', // Foreign key on articles table...
'_id', // Local key on users table...
'id' // Local key on feeds table...
);
}
I get only _id (ObjectID) with this query:
$user = \App\Models\User::find(1);
dd($user->articles);
Could you help me to search the problem?
You can try this
$user->articles()->find(1);
In place of find() you can use first() if you want the first record and if you want all records you can use get()
also if you want to put constraint use where() rather than find()
$user->articles()->where('_id', 1)->first();

Laravel Eloquent belongsTo relationship is not working

I'm trying to create a relationship between two tables using Eloquent belongsTo but it doesn't seem to work.
the two tables are documents and departments , each document belongs to one department.
documents
id INT
department INT
departments
id INT
name varchar(255)
this is the function that defines the relationship
public function department(){
// department: foreign key
// id : departments table primary key
return $this->belongsTo('\App\Department' , 'department' , 'id');
}
and this is the accessor function
public function getDepartmentAttribute(){
return $this->department()->first()->name;
}
it returns the following error message: Undefined property: App\AjaxSearch::$department
In documents table add
department_id INT Foreign
In your documents migration
$table->integer('department')->unsigned();
Also edit the relationship
public function department() {
return $this->belongsTo('App\Department', 'department');
}
Update
Ok according to your updates, you can get the department name like this
$doc = Document::find(1);
$name = $doc->department->name;
You need to check whether the related record exists
public function department()
{
return $this->belongsTo('App\Department', 'department');
}
$document is your current document record.
$name = (empty($document->department->id) === false) ? ($document->department->name) : '';

Laravel updateExistingPivot with multiple primary keys

Problem
I want to update a row in a pivot table that have 2 primary keys. But updateExistingPivot want only a single primary key.
$user = App\User::find(1);
$user->roles()->updateExistingPivot($roleId, $attributes);
My DB-tables
Campaign
User
Campaign_user (primary keys are user_id and campaign_id)
My Question
Should I change my pivot table so it only have 1 primary key called id. Or can I keep it with 2 primary keys, and still update it, with Eloquent?
I think for best practice you should add a key id in your Campaign_user table, structure should:
Campaign_user
id|user_id|campaign_id
In User Model
public function campaign()
{
return $this->belongsToMany('Campaign', 'Campaign_user','user_id','campaign_id')->withPivot('extra attribute if any');
}
In Campaign Model
public function users()
{
return $this->belongsToMany('User', 'Campaign_user','campaign_id','user_id')->withPivot('extra attribute if any');
}
Now your code is:
$user = App\User::find($userId);
$user->campaign()->updateExistingPivot($campaignId, array('any attribute'=>$value));

Categories