Laravel - Making a HasManyThrough Relationship provide a unique collection









up vote
0
down vote

favorite












I am having an issue getting a hasManyThrough to work:



public function deliveryContainers() : HasManyThrough

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)->where('delivery_id', $this->delivery_id);



Because the stockMovements table returns multiple results, my resulting delivery containers collection contains duplicate entries. If I could somehow put a group/unique on the intermediate table query then this would be resolved.



I can get a collection with the correct deliveryContainers eager loaded using the following:



public function deliveryContainers()

return $this->hasMany(StockMovement::class, 'entity_id', 'delivery_id')
->with('deliveryContainer')
->where('product_id', $this->product_id)
->get()
->unique('location_id');



However, to access the deliveryContainer I now have the following:



foreach($this->deliveryContainers() as $row)
$row->deliveryContainer->id;



And what I would like to have...



foreach($this->deliveryContainers() as $row)
$row->id;



Is there any way to push the eager loaded relationship up a level (if that can be used to describe it), or even better add some kind of unique filter to the hasManyThrough relationship?



Table Structure



delivery_exceptions (where this relationship originates)



  • product_id

  • delivery_id

delivery_containers



  • id

  • delivery_id

stock_movements



  • entity_id (linked to delivery id)

  • product_id

Relationships



  • A delivery exception belongsTo a product

  • A product hasMany stock_movements

  • A stock movement belongsTo a delivery container

  • A delivery exception hasMany delivery containers... (indirectly, through a combination of the product and the stock movements)









share|improve this question























  • How exactly do your models look like and what are their keys and other relationship definitions?
    – Namoshek
    Nov 9 at 20:43










  • Are these really all the keys and foreign keys on the delivery_containers table? Because if so, why do you need a hasManyThrough relationship at all? On delivery_exceptions, you have a delivery_id which you find again on the delivery_containers. So it looks quite straight forward to me...
    – Namoshek
    Nov 9 at 21:16










  • Delivery containers actually requires a relationship to the stock movement table in order to split the delivery into delivery containers. A delivery has many delivery containers and a delivery containers has many products. I am trying to find all delivery containers which a product from a delivery exists within
    – Adam Lambert
    Nov 9 at 21:23














up vote
0
down vote

favorite












I am having an issue getting a hasManyThrough to work:



public function deliveryContainers() : HasManyThrough

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)->where('delivery_id', $this->delivery_id);



Because the stockMovements table returns multiple results, my resulting delivery containers collection contains duplicate entries. If I could somehow put a group/unique on the intermediate table query then this would be resolved.



I can get a collection with the correct deliveryContainers eager loaded using the following:



public function deliveryContainers()

return $this->hasMany(StockMovement::class, 'entity_id', 'delivery_id')
->with('deliveryContainer')
->where('product_id', $this->product_id)
->get()
->unique('location_id');



However, to access the deliveryContainer I now have the following:



foreach($this->deliveryContainers() as $row)
$row->deliveryContainer->id;



And what I would like to have...



foreach($this->deliveryContainers() as $row)
$row->id;



Is there any way to push the eager loaded relationship up a level (if that can be used to describe it), or even better add some kind of unique filter to the hasManyThrough relationship?



Table Structure



delivery_exceptions (where this relationship originates)



  • product_id

  • delivery_id

delivery_containers



  • id

  • delivery_id

stock_movements



  • entity_id (linked to delivery id)

  • product_id

Relationships



  • A delivery exception belongsTo a product

  • A product hasMany stock_movements

  • A stock movement belongsTo a delivery container

  • A delivery exception hasMany delivery containers... (indirectly, through a combination of the product and the stock movements)









share|improve this question























  • How exactly do your models look like and what are their keys and other relationship definitions?
    – Namoshek
    Nov 9 at 20:43










  • Are these really all the keys and foreign keys on the delivery_containers table? Because if so, why do you need a hasManyThrough relationship at all? On delivery_exceptions, you have a delivery_id which you find again on the delivery_containers. So it looks quite straight forward to me...
    – Namoshek
    Nov 9 at 21:16










  • Delivery containers actually requires a relationship to the stock movement table in order to split the delivery into delivery containers. A delivery has many delivery containers and a delivery containers has many products. I am trying to find all delivery containers which a product from a delivery exists within
    – Adam Lambert
    Nov 9 at 21:23












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am having an issue getting a hasManyThrough to work:



public function deliveryContainers() : HasManyThrough

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)->where('delivery_id', $this->delivery_id);



Because the stockMovements table returns multiple results, my resulting delivery containers collection contains duplicate entries. If I could somehow put a group/unique on the intermediate table query then this would be resolved.



I can get a collection with the correct deliveryContainers eager loaded using the following:



public function deliveryContainers()

return $this->hasMany(StockMovement::class, 'entity_id', 'delivery_id')
->with('deliveryContainer')
->where('product_id', $this->product_id)
->get()
->unique('location_id');



However, to access the deliveryContainer I now have the following:



foreach($this->deliveryContainers() as $row)
$row->deliveryContainer->id;



And what I would like to have...



foreach($this->deliveryContainers() as $row)
$row->id;



Is there any way to push the eager loaded relationship up a level (if that can be used to describe it), or even better add some kind of unique filter to the hasManyThrough relationship?



Table Structure



delivery_exceptions (where this relationship originates)



  • product_id

  • delivery_id

delivery_containers



  • id

  • delivery_id

stock_movements



  • entity_id (linked to delivery id)

  • product_id

Relationships



  • A delivery exception belongsTo a product

  • A product hasMany stock_movements

  • A stock movement belongsTo a delivery container

  • A delivery exception hasMany delivery containers... (indirectly, through a combination of the product and the stock movements)









share|improve this question















I am having an issue getting a hasManyThrough to work:



public function deliveryContainers() : HasManyThrough

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)->where('delivery_id', $this->delivery_id);



Because the stockMovements table returns multiple results, my resulting delivery containers collection contains duplicate entries. If I could somehow put a group/unique on the intermediate table query then this would be resolved.



I can get a collection with the correct deliveryContainers eager loaded using the following:



public function deliveryContainers()

return $this->hasMany(StockMovement::class, 'entity_id', 'delivery_id')
->with('deliveryContainer')
->where('product_id', $this->product_id)
->get()
->unique('location_id');



However, to access the deliveryContainer I now have the following:



foreach($this->deliveryContainers() as $row)
$row->deliveryContainer->id;



And what I would like to have...



foreach($this->deliveryContainers() as $row)
$row->id;



Is there any way to push the eager loaded relationship up a level (if that can be used to describe it), or even better add some kind of unique filter to the hasManyThrough relationship?



Table Structure



delivery_exceptions (where this relationship originates)



  • product_id

  • delivery_id

delivery_containers



  • id

  • delivery_id

stock_movements



  • entity_id (linked to delivery id)

  • product_id

Relationships



  • A delivery exception belongsTo a product

  • A product hasMany stock_movements

  • A stock movement belongsTo a delivery container

  • A delivery exception hasMany delivery containers... (indirectly, through a combination of the product and the stock movements)






php laravel eloquent has-many-through






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 9 at 21:04

























asked Nov 9 at 20:10









Adam Lambert

17410




17410











  • How exactly do your models look like and what are their keys and other relationship definitions?
    – Namoshek
    Nov 9 at 20:43










  • Are these really all the keys and foreign keys on the delivery_containers table? Because if so, why do you need a hasManyThrough relationship at all? On delivery_exceptions, you have a delivery_id which you find again on the delivery_containers. So it looks quite straight forward to me...
    – Namoshek
    Nov 9 at 21:16










  • Delivery containers actually requires a relationship to the stock movement table in order to split the delivery into delivery containers. A delivery has many delivery containers and a delivery containers has many products. I am trying to find all delivery containers which a product from a delivery exists within
    – Adam Lambert
    Nov 9 at 21:23
















  • How exactly do your models look like and what are their keys and other relationship definitions?
    – Namoshek
    Nov 9 at 20:43










  • Are these really all the keys and foreign keys on the delivery_containers table? Because if so, why do you need a hasManyThrough relationship at all? On delivery_exceptions, you have a delivery_id which you find again on the delivery_containers. So it looks quite straight forward to me...
    – Namoshek
    Nov 9 at 21:16










  • Delivery containers actually requires a relationship to the stock movement table in order to split the delivery into delivery containers. A delivery has many delivery containers and a delivery containers has many products. I am trying to find all delivery containers which a product from a delivery exists within
    – Adam Lambert
    Nov 9 at 21:23















How exactly do your models look like and what are their keys and other relationship definitions?
– Namoshek
Nov 9 at 20:43




How exactly do your models look like and what are their keys and other relationship definitions?
– Namoshek
Nov 9 at 20:43












Are these really all the keys and foreign keys on the delivery_containers table? Because if so, why do you need a hasManyThrough relationship at all? On delivery_exceptions, you have a delivery_id which you find again on the delivery_containers. So it looks quite straight forward to me...
– Namoshek
Nov 9 at 21:16




Are these really all the keys and foreign keys on the delivery_containers table? Because if so, why do you need a hasManyThrough relationship at all? On delivery_exceptions, you have a delivery_id which you find again on the delivery_containers. So it looks quite straight forward to me...
– Namoshek
Nov 9 at 21:16












Delivery containers actually requires a relationship to the stock movement table in order to split the delivery into delivery containers. A delivery has many delivery containers and a delivery containers has many products. I am trying to find all delivery containers which a product from a delivery exists within
– Adam Lambert
Nov 9 at 21:23




Delivery containers actually requires a relationship to the stock movement table in order to split the delivery into delivery containers. A delivery has many delivery containers and a delivery containers has many products. I am trying to find all delivery containers which a product from a delivery exists within
– Adam Lambert
Nov 9 at 21:23












2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










You've got a really tough setup there and I'm not entirely sure that I got the full idea behind it (also because of you using entity_id at some place instead of delivery_id). But nonetheless, I gave it a shot.



The hasManyThrough relationship you defined looks actually not too bad, but in my opinion there is a better way to get to the result. But first let's have a look at your relationships:



 3
+-------------------------------------+
4 v |
+-------------> Delivery <----------+ |
| | 1 |
+ + +
DeliveryException +---> Product <---+ StockMovement +---> DeliveryContainer
+ ^
+---------------------------------------------------------+
2


As a StockMovement already belongs to a DeliveryContainer, which in return belongs to a Delivery, the relation from StockMovement to Delivery (marked as 1) seems obsolete to me. Anyway, to get relation 2 on your model, you can use the paths 3 and 4 to your advantage:



class DeliveryException

public function deliveryContainers(): HasMany

return $this->hasMany(DeliveryContainer::class, 'delivery_id', 'delivery_id');




Obviously, this will give you all the DeliveryContainers, unfiltered by the Product. Therefore I suggest adding a second function:



public function deliveryContainersByProduct(): HasMany

return $this->deliveryContainers()
->whereHas('stockMovements', function ($query)
$query->where('product_id', $this->product_id);
);






share|improve this answer




















  • Wow, thanks so much for your effort in helping on this. It works perfectly!
    – Adam Lambert
    Nov 9 at 23:54










  • I actually got something else working in the mean time (but your solution is way more elegant and I am going to switch to this now). My other solution posted as another answer for reference.
    – Adam Lambert
    Nov 10 at 0:00


















up vote
0
down vote













The accepted answer is far more elegant, but this is another way to do this too:



public function deliveryContainers1()

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)
->where('delivery_id', $this->delivery_id)
->distinct();






share|improve this answer




















  • I wonder why your solution requires a distinct() . The generated query should not retrieve duplicates without it either. But I'll give this solution a try myself, it looks interesting anyway.
    – Namoshek
    Nov 10 at 7:57










  • I think it is because it gets each delivery container for each stock movement. While the stock movements are all unique, they in turn reference the duplicated delivery containers.
    – Adam Lambert
    Nov 10 at 14:34










  • I don't think so. Because if you have three models A, B and C where A has many B and B has many C, you will also be able to create a relation saying A has many C through B. And in this scenario, the created sql query will look something like this (sql server syntax): select * from [c] inner join [b] on [b].[id] = [c].[b_id] where [b].[a_id] = ? (? is a placeholder for the id of an instance of A). So it is actually impossible to retrieve the same model twice. But of course this relationships are more straight forward than yours...
    – Namoshek
    Nov 10 at 16:52










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53232686%2flaravel-making-a-hasmanythrough-relationship-provide-a-unique-collection%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










You've got a really tough setup there and I'm not entirely sure that I got the full idea behind it (also because of you using entity_id at some place instead of delivery_id). But nonetheless, I gave it a shot.



The hasManyThrough relationship you defined looks actually not too bad, but in my opinion there is a better way to get to the result. But first let's have a look at your relationships:



 3
+-------------------------------------+
4 v |
+-------------> Delivery <----------+ |
| | 1 |
+ + +
DeliveryException +---> Product <---+ StockMovement +---> DeliveryContainer
+ ^
+---------------------------------------------------------+
2


As a StockMovement already belongs to a DeliveryContainer, which in return belongs to a Delivery, the relation from StockMovement to Delivery (marked as 1) seems obsolete to me. Anyway, to get relation 2 on your model, you can use the paths 3 and 4 to your advantage:



class DeliveryException

public function deliveryContainers(): HasMany

return $this->hasMany(DeliveryContainer::class, 'delivery_id', 'delivery_id');




Obviously, this will give you all the DeliveryContainers, unfiltered by the Product. Therefore I suggest adding a second function:



public function deliveryContainersByProduct(): HasMany

return $this->deliveryContainers()
->whereHas('stockMovements', function ($query)
$query->where('product_id', $this->product_id);
);






share|improve this answer




















  • Wow, thanks so much for your effort in helping on this. It works perfectly!
    – Adam Lambert
    Nov 9 at 23:54










  • I actually got something else working in the mean time (but your solution is way more elegant and I am going to switch to this now). My other solution posted as another answer for reference.
    – Adam Lambert
    Nov 10 at 0:00















up vote
1
down vote



accepted










You've got a really tough setup there and I'm not entirely sure that I got the full idea behind it (also because of you using entity_id at some place instead of delivery_id). But nonetheless, I gave it a shot.



The hasManyThrough relationship you defined looks actually not too bad, but in my opinion there is a better way to get to the result. But first let's have a look at your relationships:



 3
+-------------------------------------+
4 v |
+-------------> Delivery <----------+ |
| | 1 |
+ + +
DeliveryException +---> Product <---+ StockMovement +---> DeliveryContainer
+ ^
+---------------------------------------------------------+
2


As a StockMovement already belongs to a DeliveryContainer, which in return belongs to a Delivery, the relation from StockMovement to Delivery (marked as 1) seems obsolete to me. Anyway, to get relation 2 on your model, you can use the paths 3 and 4 to your advantage:



class DeliveryException

public function deliveryContainers(): HasMany

return $this->hasMany(DeliveryContainer::class, 'delivery_id', 'delivery_id');




Obviously, this will give you all the DeliveryContainers, unfiltered by the Product. Therefore I suggest adding a second function:



public function deliveryContainersByProduct(): HasMany

return $this->deliveryContainers()
->whereHas('stockMovements', function ($query)
$query->where('product_id', $this->product_id);
);






share|improve this answer




















  • Wow, thanks so much for your effort in helping on this. It works perfectly!
    – Adam Lambert
    Nov 9 at 23:54










  • I actually got something else working in the mean time (but your solution is way more elegant and I am going to switch to this now). My other solution posted as another answer for reference.
    – Adam Lambert
    Nov 10 at 0:00













up vote
1
down vote



accepted







up vote
1
down vote



accepted






You've got a really tough setup there and I'm not entirely sure that I got the full idea behind it (also because of you using entity_id at some place instead of delivery_id). But nonetheless, I gave it a shot.



The hasManyThrough relationship you defined looks actually not too bad, but in my opinion there is a better way to get to the result. But first let's have a look at your relationships:



 3
+-------------------------------------+
4 v |
+-------------> Delivery <----------+ |
| | 1 |
+ + +
DeliveryException +---> Product <---+ StockMovement +---> DeliveryContainer
+ ^
+---------------------------------------------------------+
2


As a StockMovement already belongs to a DeliveryContainer, which in return belongs to a Delivery, the relation from StockMovement to Delivery (marked as 1) seems obsolete to me. Anyway, to get relation 2 on your model, you can use the paths 3 and 4 to your advantage:



class DeliveryException

public function deliveryContainers(): HasMany

return $this->hasMany(DeliveryContainer::class, 'delivery_id', 'delivery_id');




Obviously, this will give you all the DeliveryContainers, unfiltered by the Product. Therefore I suggest adding a second function:



public function deliveryContainersByProduct(): HasMany

return $this->deliveryContainers()
->whereHas('stockMovements', function ($query)
$query->where('product_id', $this->product_id);
);






share|improve this answer












You've got a really tough setup there and I'm not entirely sure that I got the full idea behind it (also because of you using entity_id at some place instead of delivery_id). But nonetheless, I gave it a shot.



The hasManyThrough relationship you defined looks actually not too bad, but in my opinion there is a better way to get to the result. But first let's have a look at your relationships:



 3
+-------------------------------------+
4 v |
+-------------> Delivery <----------+ |
| | 1 |
+ + +
DeliveryException +---> Product <---+ StockMovement +---> DeliveryContainer
+ ^
+---------------------------------------------------------+
2


As a StockMovement already belongs to a DeliveryContainer, which in return belongs to a Delivery, the relation from StockMovement to Delivery (marked as 1) seems obsolete to me. Anyway, to get relation 2 on your model, you can use the paths 3 and 4 to your advantage:



class DeliveryException

public function deliveryContainers(): HasMany

return $this->hasMany(DeliveryContainer::class, 'delivery_id', 'delivery_id');




Obviously, this will give you all the DeliveryContainers, unfiltered by the Product. Therefore I suggest adding a second function:



public function deliveryContainersByProduct(): HasMany

return $this->deliveryContainers()
->whereHas('stockMovements', function ($query)
$query->where('product_id', $this->product_id);
);







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 9 at 21:48









Namoshek

2,5552718




2,5552718











  • Wow, thanks so much for your effort in helping on this. It works perfectly!
    – Adam Lambert
    Nov 9 at 23:54










  • I actually got something else working in the mean time (but your solution is way more elegant and I am going to switch to this now). My other solution posted as another answer for reference.
    – Adam Lambert
    Nov 10 at 0:00

















  • Wow, thanks so much for your effort in helping on this. It works perfectly!
    – Adam Lambert
    Nov 9 at 23:54










  • I actually got something else working in the mean time (but your solution is way more elegant and I am going to switch to this now). My other solution posted as another answer for reference.
    – Adam Lambert
    Nov 10 at 0:00
















Wow, thanks so much for your effort in helping on this. It works perfectly!
– Adam Lambert
Nov 9 at 23:54




Wow, thanks so much for your effort in helping on this. It works perfectly!
– Adam Lambert
Nov 9 at 23:54












I actually got something else working in the mean time (but your solution is way more elegant and I am going to switch to this now). My other solution posted as another answer for reference.
– Adam Lambert
Nov 10 at 0:00





I actually got something else working in the mean time (but your solution is way more elegant and I am going to switch to this now). My other solution posted as another answer for reference.
– Adam Lambert
Nov 10 at 0:00













up vote
0
down vote













The accepted answer is far more elegant, but this is another way to do this too:



public function deliveryContainers1()

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)
->where('delivery_id', $this->delivery_id)
->distinct();






share|improve this answer




















  • I wonder why your solution requires a distinct() . The generated query should not retrieve duplicates without it either. But I'll give this solution a try myself, it looks interesting anyway.
    – Namoshek
    Nov 10 at 7:57










  • I think it is because it gets each delivery container for each stock movement. While the stock movements are all unique, they in turn reference the duplicated delivery containers.
    – Adam Lambert
    Nov 10 at 14:34










  • I don't think so. Because if you have three models A, B and C where A has many B and B has many C, you will also be able to create a relation saying A has many C through B. And in this scenario, the created sql query will look something like this (sql server syntax): select * from [c] inner join [b] on [b].[id] = [c].[b_id] where [b].[a_id] = ? (? is a placeholder for the id of an instance of A). So it is actually impossible to retrieve the same model twice. But of course this relationships are more straight forward than yours...
    – Namoshek
    Nov 10 at 16:52














up vote
0
down vote













The accepted answer is far more elegant, but this is another way to do this too:



public function deliveryContainers1()

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)
->where('delivery_id', $this->delivery_id)
->distinct();






share|improve this answer




















  • I wonder why your solution requires a distinct() . The generated query should not retrieve duplicates without it either. But I'll give this solution a try myself, it looks interesting anyway.
    – Namoshek
    Nov 10 at 7:57










  • I think it is because it gets each delivery container for each stock movement. While the stock movements are all unique, they in turn reference the duplicated delivery containers.
    – Adam Lambert
    Nov 10 at 14:34










  • I don't think so. Because if you have three models A, B and C where A has many B and B has many C, you will also be able to create a relation saying A has many C through B. And in this scenario, the created sql query will look something like this (sql server syntax): select * from [c] inner join [b] on [b].[id] = [c].[b_id] where [b].[a_id] = ? (? is a placeholder for the id of an instance of A). So it is actually impossible to retrieve the same model twice. But of course this relationships are more straight forward than yours...
    – Namoshek
    Nov 10 at 16:52












up vote
0
down vote










up vote
0
down vote









The accepted answer is far more elegant, but this is another way to do this too:



public function deliveryContainers1()

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)
->where('delivery_id', $this->delivery_id)
->distinct();






share|improve this answer












The accepted answer is far more elegant, but this is another way to do this too:



public function deliveryContainers1()

return $this->hasManyThrough(
DeliveryContainer::class, // Final
StockMovement::class, // Intermediate
'product_id', // Foreign key on Intermediate
'id', // Foreign key on Final
'product_id', // Local key on Current
'location_id' // Local key on Intermediate
)
->where('delivery_id', $this->delivery_id)
->distinct();







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 10 at 0:02









Adam Lambert

17410




17410











  • I wonder why your solution requires a distinct() . The generated query should not retrieve duplicates without it either. But I'll give this solution a try myself, it looks interesting anyway.
    – Namoshek
    Nov 10 at 7:57










  • I think it is because it gets each delivery container for each stock movement. While the stock movements are all unique, they in turn reference the duplicated delivery containers.
    – Adam Lambert
    Nov 10 at 14:34










  • I don't think so. Because if you have three models A, B and C where A has many B and B has many C, you will also be able to create a relation saying A has many C through B. And in this scenario, the created sql query will look something like this (sql server syntax): select * from [c] inner join [b] on [b].[id] = [c].[b_id] where [b].[a_id] = ? (? is a placeholder for the id of an instance of A). So it is actually impossible to retrieve the same model twice. But of course this relationships are more straight forward than yours...
    – Namoshek
    Nov 10 at 16:52
















  • I wonder why your solution requires a distinct() . The generated query should not retrieve duplicates without it either. But I'll give this solution a try myself, it looks interesting anyway.
    – Namoshek
    Nov 10 at 7:57










  • I think it is because it gets each delivery container for each stock movement. While the stock movements are all unique, they in turn reference the duplicated delivery containers.
    – Adam Lambert
    Nov 10 at 14:34










  • I don't think so. Because if you have three models A, B and C where A has many B and B has many C, you will also be able to create a relation saying A has many C through B. And in this scenario, the created sql query will look something like this (sql server syntax): select * from [c] inner join [b] on [b].[id] = [c].[b_id] where [b].[a_id] = ? (? is a placeholder for the id of an instance of A). So it is actually impossible to retrieve the same model twice. But of course this relationships are more straight forward than yours...
    – Namoshek
    Nov 10 at 16:52















I wonder why your solution requires a distinct() . The generated query should not retrieve duplicates without it either. But I'll give this solution a try myself, it looks interesting anyway.
– Namoshek
Nov 10 at 7:57




I wonder why your solution requires a distinct() . The generated query should not retrieve duplicates without it either. But I'll give this solution a try myself, it looks interesting anyway.
– Namoshek
Nov 10 at 7:57












I think it is because it gets each delivery container for each stock movement. While the stock movements are all unique, they in turn reference the duplicated delivery containers.
– Adam Lambert
Nov 10 at 14:34




I think it is because it gets each delivery container for each stock movement. While the stock movements are all unique, they in turn reference the duplicated delivery containers.
– Adam Lambert
Nov 10 at 14:34












I don't think so. Because if you have three models A, B and C where A has many B and B has many C, you will also be able to create a relation saying A has many C through B. And in this scenario, the created sql query will look something like this (sql server syntax): select * from [c] inner join [b] on [b].[id] = [c].[b_id] where [b].[a_id] = ? (? is a placeholder for the id of an instance of A). So it is actually impossible to retrieve the same model twice. But of course this relationships are more straight forward than yours...
– Namoshek
Nov 10 at 16:52




I don't think so. Because if you have three models A, B and C where A has many B and B has many C, you will also be able to create a relation saying A has many C through B. And in this scenario, the created sql query will look something like this (sql server syntax): select * from [c] inner join [b] on [b].[id] = [c].[b_id] where [b].[a_id] = ? (? is a placeholder for the id of an instance of A). So it is actually impossible to retrieve the same model twice. But of course this relationships are more straight forward than yours...
– Namoshek
Nov 10 at 16:52

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53232686%2flaravel-making-a-hasmanythrough-relationship-provide-a-unique-collection%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Darth Vader #20

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Ondo