How to get hasMany relationship data

Asked

Viewed 630 times

3

I have a table Grupo and a Topicos, where the group has many topics and this is my code:

public function topicos()
{
    return $this->hasMany('App\Topico');
}

In my Controller is like this:

public function grupo($slug)
{
    $grupo = Grupo::where('slug', $slug)->first();
    return view('grupo', compact('grupo'));
}

However, in this way I cannot access the data of the two tables through a single foreach, I’d like to take the data like this:

$grupo->topicos->titulo

but it doesn’t work and instead of using first() I have to use get() and then make two foreach so you can get all the data.

The problem is that there are several pieces of code that I need to enter just the group id, and have to do a foreach just for that seems unnecessary.

1 answer

2


In your code and in your question you have explicitly stated a relation 1:N (one for many), where the group has several topics and a topic is from a group. On the site there are several explanations of how this relationship works, example:

how your settings are not present as information in your question and I imagine your relationship settings are correct:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Grupo extends Model
{        
    public function topicos()
    {        
        return $this->hasMany('App\Topico','grupo_id', 'id');
    }    
}

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Topico extends Model
{        
    public function grupo()
    {        
        return $this->belongsTo('App\Grupo','grupo_id', 'id');
    }    
}

this example of a relationship that I imagine to be your.

To search the items of the Group Link with Topics:

$grupo = Grupo::with('topicos')->where('slug', $slug)->first();

will have the group items and in the list of topics a collection, and this is how it was set up, but if you want to bring in the relation only one topic also gives (i understood that you need to bring only one topic I found this strange, but, there is the possibility to make a filter in the relation and limit the number of returned items), example:

$grupo = Grupo::with(['topicos' => function($query){$query->limit(1);}])
    ->where('slug', $slug)->first();

and to recover even bringing a collection item (which would be good because of the performance, by bringing only what needs):

{{ $grupo->topicos[0]->titulo }}

because what counts in all this is the relation being that topics always generates a list, but with this code above restricts only one item to be brought in the SQL.

Observing: it is also good to remember that the early shipment made with with is optimized, generating in case two SQL otherwise if the load is done at runtime it is bad to generate in each interaction an instruction SQL to the database.

  • 1

    That’s what I needed to understand. In my case, I need to take all the topics of a group and display. It’s a special discussion forum. But your explanation made me better understand what I’m doing. Thank you very much

Browser other questions tagged

You are not signed in. Login or sign up in order to post.