Laravel get nested relationship from polymorphic table - laravel

I want to get nested relationship data from polymorphic table, I'm using MongoDB as database in my laravel app so you might notice that i don't use pivot table between movies and genres table for many to many relationship given the example below.
So what I want to achieve is to get the nested data like frontends > genres > movies all in one result.
let's say I have polymorphic frontends table, looks like this
frontends
id - integer
position - integer
frontable_id - integer
frontable_type - string
genres
id - integer
name - string
movie_ids - array[]
movies
id - integer
title - string
genre_ids - array[]
This is the model I have set
use Jenssegers\Mongodb\Eloquent\Model;
class Frontend extends Model
{
public function frontable()
{
return $this->morphTo(__FUNCTION__, 'frontable_type_api', 'frontable_id');
}
}
class Genre extends Model
{
public function movies()
{
return $this->belongsToMany(Movie::class, null, 'genre_ids', 'movie_ids');
}
}
class Movie extends Model
{
public function genres()
{
return $this->belongsToMany(Genre::class, null, 'movie_ids', 'category_ids');
}
}
What i have tried is to get the frontend table first and then its frontable_id relationship, not until the movies table
$frontends = Frontend::with('frontable.movies')->orderBy('position')->get();
return $frontends;
The relation movies has been declared in related model, but it won't get the movies data

Related

Laravel 8 - How to relationship from 3 tables

I have 3 tables:
structurals
id
name
indicators
id
name
groupings
id
structural_id
indicator_id
And Result:
#structural name
indicator name
indicator name
#structuralname
indicator name
I've used method hasMany & hasManyThrough but errors.
In this case, an indicator may belong to one or more structural. And a structural can have one or more indicators.
What this describes is a many-to-many relationship where groupings is only a pivot table. So you should be using the belongsToMany instead:
class Indicator extends Model
{
public function structurals()
{
return $this->belongsToMany(Structural::class, 'groupings');
}
}
class Structural extends Model
{
public function indicators()
{
return $this->belongsToMany(Indicator::class, 'groupings');
}
}
Docs: https://laravel.com/docs/eloquent-relationships#many-to-many
You can also remove the id column from the groupings table, as it is unnecessary.

Get data from eloquent relationship with pivot in laravel

I have 3 DB table.
shows
show_genres
show_show_genre
In my show model, i have:
public function genres()
{
return $this->belongsToMany('App\ShowGenre');
}
So when i do:
$show=Show::find(1);
$show->genres give me collection with all genres that have show_id in shows_genres db.
I have also ShowGenre model where is all genres i have and i use.
Becouse i want to use sync for my genres, that names need to be in database.
But how can i find all shows that have genre id.
I couldn't find any way to get that list. Please help, thanks.
Edit:
You should do this other way around:
Have a model for Genre
your relationship method in Genre model should be
public function shows()
{
return $this->belongsToMany('App\Show', 'shows_genres');
}
belongsToMany accepts two parameters, model and pivot table name if not a standard name.
Your solution:
//Get genre 'strict'
//where could be followed by column name example:whereSlug, whereName
$strictGenre = Genre::whereName('strict')->first();
if($strictGenre)
{
//get shows of this genre
$strictShows = $strictGenre->shows;
}
Read manytomany relationships:
https://laravel.com/docs/6.x/eloquent-relationships#many-to-many
You may use
$show->genres()
->wherePivot('column', value)
->get();
By default Pivot table name must be singular : show_genre (without
plural s)
See docs
Assuming you have this relationship in your genres model
public function shows()
{
return $this->belongsToMany('App\Show', 'shows_genres', 'genre_id', 'show_id');
}
Then you can directly get all shows by genres id like this
$shows = Genre::find($id)->shows;

Laravel whereHas ManyToMany relation but then order by a value in the third table

I have 3 tables
entry (
id,
title,
other_stuff)
entry_award (
id,
award_id,
entry_id)
award (
id,
name,
type)
I am trying to create a laravel query which lets me get all the entries that have awards, and order them by award.type ASC
$Entries = Entry::with('award')
->whereHas('award', function ($query) {
$query->orderBy('award.award_id','ASC');
})->paginate(20);
But this doesn't work.
This is the sql version of it
SELECT DISTINCT entry.*
FROM entry, award, entry_award
WHERE entry.id = entry_award.entry_id
AND award.id = entry_award.award_id
ORDER BY award.type ASC;
Now I tried to just use the raw sql for it, but the problem seems to be that laravel does not then recognize the result as Entry models/objects. And i need to get other Entry relations later on in the html via blade.
So how can I either make a query-builder query that gets me all entries that have awards and orders them by award.type value
or use the raw sql but have Laravel see it as an array of Entry
objects instead of just an array of JSON values.
class Entry extends Model {
public function entry_award(){
return $this->belongsToMany('App\Award', 'entry_award');
}
}
class Award extends Model {
public function entries() {
return $this->belongsToMany('App\Entry', 'entry_award');
}
}

Join 3 tables using Laravel Eloquent

So I have 3 tables
size_sets - id, name
sizes - id, name
size_set_sizes - size_id, size_set_id
I want to define a relationship in size_set model that would retrieve all sizes available for that sizeset
Something like:
public function sizes()
{
//define relationship here
}
Method sizes should retrieve the names from the size table, through size_set_sizes table in the size_set model...
My application is very dynamic and thus I needed to go with this structure. I tried the hasManyThrough relationship, but couldn't get that to work.
100% use a pivot table
https://laravel.com/docs/5.4/eloquent-relationships
This link will give you all you need
Use belongsToMany() relations like:
class Size extends Model
{
public function sizeSets()
{
return $this->belongsToMany(SizeSet::class, 'size_set_sizes');
}
}
class SizeSet extends Model
{
public function sizes()
{
return $this->belongsToMany(Size::class, 'size_set_sizes');
}
}
Then you can do:
$sizeSet = SizeSet::with('sizes')->find($id);
Then $sizeSet->sizes will return a collection of sizes for that size set.
I Think I found what I was looking for The answer is a pivot-table
http://laraveldaily.com/pivot-tables-and-many-to-many-relationships/

Correct relationship in Laravel

I have four tables in database: groups, specialties, lessons, group_lesson. It's structures:
groups
id
specialty_id
name
specialties
id
name
lessons
id
specialty_id
group_lesson (UNIQUE INDEX lesson_id, group_id)
lesson_id
group_id
date
My models look like that for now:
class Group extends Eloquent {
public function specialty() {
return $this->belongsTo('Specialty');
}
}
class Lesson extends Eloquent {
public function specialty() {
return $this->belongsTo('Specialty');
}
}
class Specialty extends Eloquent {
public function lessons() {
return $this->hasMany('Lesson');
}
public function groups() {
return $this->hasMany('Group');
}
}
I need get additional fields in Group model look like that
Group - Eloquent model
name - string
lessons - collection of Lesson models of Group Specialty
date - date from group_lesson table
I've tried different relationships and combinations, but it's doesn't work. Please help me to write correct relationships.
You can use eager-loading to access relational data through relationships, and can even chain relationships further. As a rule of thumb, if you can draw a path to from 1 model to another through a relationship, you can eagerload all the relevant and relational data for that with chained eager-loads.
Laravel Eager Loading
As an example
$speciality_group = Speciality::with('group','lessons')->find($id);
Even though you are only getting a single instance of the speciality model, the related data is hasMany, meaning multiple records. You need to loop through these records using a foreach loop to access the relevant data for them, or alternitavely add additional closures in your initial query to load only a single related model.
foreach($speciality_group->group as $group)
{
echo $group->name;
}
You will need to do this for both instances where you want to display related information.

Resources