Support the ongoing development of Laravel.io →
Database Eloquent Installation
Last updated 2 years ago.
0

Make sure you have set all relations in the models, then:

$posts = App\Post::whereHas('collected_item', function($query) use ($q) {
    $query->whereHas('item_model', function($query) use ($q) {
        $query->where('model_name', 'like', $q . '%');
    });
});

Not sure though, never go deeper then 1 level when it comes to querying relationships.

0

It works, but this is done without using the hasManyThrough method defined in Item_model, as per laravel docs retrieving posts with the hasManyThrough method should be a matter of $item->post which doesn't work. I could delete the hasManyThrough stuff from the Item_model completely and that would work anyway. So this is not the solution.

Last updated 7 years ago.
0

If I read it correctly on laravel.com docs, your second code snippet actually does what it should. It will retrieve the item_model with the posts attached.

$item->posts should give you a collection with posts.

If you only want the posts, you need to start with the Post model or use collection methods and get them the hard way.

PS: you tell me my code works, but why does it have to be with the hasManyThrough relation?

0

Well it doesn't. If I do

$models_with_posts = Item_model::where('model_name', 'LIKE', $q . '%')->has('posts')->with('posts')->get();

I get the model with the posts, then I do

$posts = $models_with_posts->posts;

result:

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

Even if your code works what I'm trying to understand is why in heaven the hasManyThrough method, which should easily retrieve all the posts for a model, it not working at all.

0

Damn it, now you made me curious :p

How is the relation between item_model and collected_item defined? I don't see a item_model_id in your collected_item model.

I believe you need to add 1 more parameter to your hasManyThrough method

$this->hasManyThrough('App\Post', 'App\Collected_item', 'model_id', 'collected_item_id', 'id');
0

Actually hasManythrough only accepts 4 arguments: "The first argument passed to the hasManyThrough method is the name of the final model we wish to access, while the second argument is the name of the intermediate model. The third argument is the name of the foreign key on the intermediate model, while the fourth argument is the name of the foreign key on the final model."

here's the relations you asked:

class collected_item extends Model
{

public function Item_model(){

        return $this->hasOne('App\Item_model', 'id', 'model_id');

    }
}
class Item_model extends Model
{
    
    public function collected_item(){
        return $this->belongsToMany('App\Collected_item');
    }
   
}
0

It accepts 5

From the laravel api: hasManyThrough

0

I believe your relations are wrong for what you are trying to achieve.

It should be:

  • Item_model hasMany collected_item
  • collected_item belongsTo item_model
  • collected_item hasMany posts
  • posts belongsTo collected_item

A belongsToMany (many-to-many) relation like you have in your item_model model, you need an intermediate table to store the relationship between item_model and collected_item.

Last updated 7 years ago.
0

even adding 'id' as 5th argument doesn't change anything. Same error.

0

LaurentMeganck said:

I believe your relations are wrong for what you are trying to achieve.

It should be:

Item_model hasMany collected_item collected_item belongsTo item_model collected_item hasMany posts posts belongsTo collected_item

A belongsToMany (many-to-many) relation like you have in your item_model model, you need an intermediate table to store the relationship between item_model and collected_item.

... hm I don't know. My "collected_item" is unique as it has other relations regarding item_model characteristics, so for example a collected guitar hasOne Guitar_Item not Many, only one.

and I forgot to add the relationship between collected_item and posts that is like this:

class collected_item extends Model
{

public function post(){

        return $this->belongsToMany('App\Post');
    }
}

because there can be MANY posts regarding the same collected item

and

class Post extends Model
{

 public function collected_item(){

        return $this->belongsTo('App\Collected_item')->with('Item_model','Designer', 'Some_Stuff');
    }
}

because a post belongsTo one and only one Collected_item

it's the item model that belongsToMany Collected_item

0

Hi, chriz74x ofcourse Call to undefined method Illuminate\Database\Query\Builder::posts() because you can't use the relations on QueryBuilder and \Illuminate\Database\Eloquent\Collections u can use relations only on instances of Illuminate\Database\Eloquent\Model.

Last updated 7 years ago.
0

jasonrust said:

Hi, chriz74x ofcourse Call to undefined method Illuminate\Database\Query\Builder::posts() because you can't use the relations on QueryBuilder and \Illuminate\Database\Eloquent\Collections u can use relations only on instances of Illuminate\Database\Eloquent\Model

So what is the solution to retrieve the posts? What is the syntax?

0

LaurentMeganck said:

I believe your relations are wrong for what you are trying to achieve.

It should be:

  • Item_model hasMany collected_item
  • collected_item belongsTo item_model
  • collected_item hasMany posts
  • posts belongsTo collected_item

A belongsToMany (many-to-many) relation like you have in your item_model model, you need an intermediate table to store the relationship between item_model and collected_item.

I tried to modify the relationships as you suggested, it broke everything and the hasManyThrough method still doesn't work

0

chriz74x said:

jasonrust said:

Hi, chriz74x ofcourse Call to undefined method Illuminate\Database\Query\Builder::posts() because you can't use the relations on QueryBuilder and \Illuminate\Database\Eloquent\Collections u can use relations only on instances of Illuminate\Database\Eloquent\Model

So what is the solution to retrieve the posts? What is the syntax?

$item_models = Item_model::where('model_name', 'LIKE', $q . '%')->has('posts')->get();

foreach($item_models as $item)
{
    dd($item->posts()); // Now you will get the item's posts. 
}
0

It really retrieved everything but the posts.

HasManyThrough {#232 ▼
  #farParent: Item_model {#231 ▶}
  #firstKey: "model_id"
  #secondKey: "collected_item_id"
  #localKey: "id"
  #query: Builder {#228 ▶}
  #parent: collected_item {#219 ▶}
  #related: Post {#233 ▶}
}
Last updated 7 years ago.
0

jasonrust said:

chriz74x said:

jasonrust said:

Hi, chriz74x ofcourse Call to undefined method Illuminate\Database\Query\Builder::posts() because you can't use the relations on QueryBuilder and \Illuminate\Database\Eloquent\Collections u can use relations only on instances of Illuminate\Database\Eloquent\Model

So what is the solution to retrieve the posts? What is the syntax?

$item_models = Item_model::where('model_name', 'LIKE', $q . '%')->has('posts')->get();

foreach($item_models as $item)
{
   dd($item->posts()); // Now you will get the item's posts. 
}

I'm sorry but this isn't really working, only if I get the models with posts initially then I can see the posts:

$models = Item_model::where('model_name', 'LIKE', $q . '%')->has('posts')->with('posts')->get();

per se the method is not retrieving any post, it's the initial query that is getting those. Maybe I don't get how this hasManyThrough relation is meant to work but it doesn't seem it's retrieving anything here...

Last updated 7 years ago.
0

chriz74x said:

jasonrust said:

chriz74x said:

jasonrust said:

Hi, chriz74x ofcourse Call to undefined method Illuminate\Database\Query\Builder::posts() because you can't use the relations on QueryBuilder and \Illuminate\Database\Eloquent\Collections u can use relations only on instances of Illuminate\Database\Eloquent\Model

So what is the solution to retrieve the posts? What is the syntax?

$item_models = Item_model::where('model_name', 'LIKE', $q . '%')->has('posts')->get();

foreach($item_models as $item)
{
   dd($item->posts()); // Now you will get the item's posts. 
}

I'm sorry but this isn't really working, only if I get the models with posts initially then I can see the posts:

$models = Item_model::where('model_name', 'LIKE', $q . '%')->has('posts')->with('posts')->get();

per se the method is not retrieving any post, it's the initial query that is getting those. Maybe I don't get how this hasManyThrough relation is meant to work but it doesn't seem it's retrieving anything here...

You can't use relations on a non-object instance, to call the relation the first u must make the select (->get() or ->first()). As i understand, in your situation better to use laravel#joins, hope should it help.

Last updated 7 years ago.
0

jasonrust said:

chriz74x said:

jasonrust said:

chriz74x said:

jasonrust said:

Hi, chriz74x ofcourse Call to undefined method Illuminate\Database\Query\Builder::posts() because you can't use the relations on QueryBuilder and \Illuminate\Database\Eloquent\Collections u can use relations only on instances of Illuminate\Database\Eloquent\Model

So what is the solution to retrieve the posts? What is the syntax?

$item_models = Item_model::where('model_name', 'LIKE', $q . '%')->has('posts')->get();

foreach($item_models as $item)
{
   dd($item->posts()); // Now you will get the item's posts. 
}

I'm sorry but this isn't really working, only if I get the models with posts initially then I can see the posts:

$models = Item_model::where('model_name', 'LIKE', $q . '%')->has('posts')->with('posts')->get();

per se the method is not retrieving any post, it's the initial query that is getting those. Maybe I don't get how this hasManyThrough relation is meant to work but it doesn't seem it's retrieving anything here...

You can't use relations on a non-object instance, to call the relation the first u must make the select (->get() or ->first()). As i understand in your situation u can use laravel#joins, hope should it help.

excuse me ... I am making the select with get() .. indeed I am retrieving all the models that have posts, then as suggested I am looping through the collection to retrieve the distant relation (posts).. but the point is that that method is not retrieving any post, indeed only if I retrieve the collection with('posts') then I am able to see those in the relations. But it's not the hasManyThrough method that is retrieving them, they were already there from the beginning.

0

Here how should show your query:

(new Collected_item)
    ->join("item_model", "collected_item.model_id", "=", "item_model.id")
    ->join("posts", "collected_item.id", "=", "posts.collected_item_id")
    ->select("item_model.*", "collected_item.*", "posts.*")
    ->where("item_model.name", 'LIKE',  $q . '%')
    ->has('posts') // but about this statement i am care. better change this scope with true where declaration and w/e it will not work because as u can see i was changed the object query model from Item_model to Collected_item
    ->get();
Last updated 7 years ago.
0

The join method worked for me. Here's how I did it, in case someone else has the same problem. https://laracasts.com/discuss/channels/laravel/how-to-query-a-distant-relation

I decided to do away with the hasManyThroughs since I could not get them to work.

Last updated 7 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

chriz74x chriz74x Joined 8 Apr 2015

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.