Rockwell Rice
Rockwell Rice

Reputation: 3002

How to retrieve a hasManyThrough in Laravel 5 controller

I have a setup where Spaces have posts, and posts may have links. I need to filter out links that belong to private spaces. Links table does not have a space_id column so it is my understanding that hasMany through could work for getting the links that belong to a space through the posts table.

I did google this, read the docs, and follow the suggested links here on SO but was unable to find anything that showed me the way.

I am getting an error as well with the lastest attempts

Undefined property: Illuminate\Database\Eloquent\Collection::$links

Space.php

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

/** 
* A Space can have links through posts.
*
* The first argument passed to the hasManyThrough method is the name of the final model we wish to access
* The second argument is the name of the intermediate model
*
* 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
*
*/

public function links() {
  return $this->hasManyThrough('App\Link', 'App\Post','space_id','post_id');
} 

Post.php

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

/** A Post belongs to a space.
*
*
*/
public function space() {
  return $this->belongsTo('App\Space');
} 

Link.php

public function post() {
    return $this->belongsTo('App\Post');
}

What I am trying in the links controller is different variations of this

$private = Space::where('spaces.isPublic','=', 0)->get();
$privateLinks = $private->links();

but I have not been able to get it to work and am wondering if someone can show me the path there.

Thanks.

Upvotes: 1

Views: 354

Answers (1)

Jeff
Jeff

Reputation: 25231

$private->links() returns a query builder, not a set of links. You can use $private->links (no ()) to get the collection of links themselves, or you can use get() on the query builder to retrieve them. The query builder allows you to provide filters on the query, like $private->links()->where('foo','bar')->get(), but you have to call get() before you have the links.

$private = Space::where('spaces.isPublic','=', 0)->get(); also returns a collection of Spaces.

You could do something like $private[0]->links or change it to $private = Space::where('spaces.isPublic','=', 0)->first() to get just the first private space, or you could go through all of the private spaces and do something with their links like:

foreach($private as $pr){ 
    $links = $pr->links;
    //dosomething
}

Upvotes: 1

Related Questions