Load specific relationships in nested impatient download in laravel

I have the following related tables:

tableA - id - value tableB - id - tableA_id - value tableC - id - tableB_id - value tableD - id - tableC_id - value 

I usually use a nested download load to get the tableaA object from tableD, for example:

 $table_d = TableD::with('TableC.TableB.TableA')->find($id); 

And I get an object like this:

 { "id": 1, "value": "value", "tableC_id": 1, "tablec": { "id": 1, "value": "value", "tableB_id": 1, "tableb": { "id": 1, "value": "value", "tableA_id": 1, "tablea": { "id": 1, "value": "value" } } } } 

What I want to achieve is to get only the object of table D associated with its object from table A, without table C and table B in the final object, something like this:

 { "id": 1, "value": "value", "tablea": { "id": 1, "value": "value" } } } 

I tried adding this function to the table D model model file:

 public function TableA() { return $this->belongsTo('App\Models\TableC', 'tableC_id') ->join('tableB','tableC.tableB_id','=','tableB.id') ->join('tableA','tableB.tableA_id','=','tableA.id') ->select('tableA.id', 'tableA.value'); } 

but this will not work, because when I make the following query, it returns some nice objects and others with tableA = null:

 $tables_d = TableD::with('TableA')->get() 

Am I doing something wrong or is there another way to achieve what I want?

+5
source share
3 answers

You can usually use a, it has many cross-cutting relationships for matching tables when there are only two tables and a table of links between them. You have one more connection outside of this, so in reality it will not be much better than what you currently have.

Have you looked at another mapping table from D to A directly or a bit of denormalization? If you always need to load it like this, you can benefit from the fact that the duplicate bit will be stored in the connections.

It will really depend on your needs, and itโ€™s not 3NF (third normal form), maybe itโ€™s not even 2NF, but why denormalization is like using a comma ... usually follow the rules, but break them for certain reasons; in this case, reduce the number of joins needed by duplicating the FK link in the table.

https://laravel.com/docs/5.6/eloquent-relationships#has-many-through

+1
source

You can skip the table with this->hasManyThrough() , but depending on what you really want to use as "future functions", you may have several relationships with any code that you want according to your needs. QueryScopes as well.

+1
source

You can try: - add a method to the TableD Model:

 public function table_a() { return $this->TableC->TableB->TableA(); } 

then use: TableD::with(table_a);

0
source

Source: https://habr.com/ru/post/1275543/


All Articles