Reputation: 1621
I have a series of database tables that store estimating information. I am trying to return all data from all database tables when certain perimeters are set.
Collection
$estimateItems = new Collection();
$estimateItems = $estimateItems->merge( $this->getBoxVent() );
$estimateItems = $estimateItems->merge( $this->getCoatings() );
$estimateItems = $estimateItems->merge( $this->getCounterFlashing() );
$estimateItems = $estimateItems->merge( $this->getDripEdge() );
$estimateItems = $estimateItems->merge( $this->getFasteners() );
$estimateItems = $estimateItems->merge( $this->getHeadwallFlashing() );
$estimateItems = $estimateItems->merge( $this->getHipcap() );
$estimateItems = $estimateItems->merge( $this->getIceShield() );
$estimateItems = $estimateItems->merge( $this->getPipeFlashing() );
$estimateItems = $estimateItems->merge( $this->getRidgecap() );
$estimateItems = $estimateItems->merge( $this->getRidgeVentilation() );
$estimateItems = $estimateItems->merge( $this->getSheathing() );
$estimateItems = $estimateItems->merge( $this->getShingles() );
$estimateItems = $estimateItems->merge( $this->getSidewallFlashing() );
$estimateItems = $estimateItems->merge( $this->getSkylights() );
$estimateItems = $estimateItems->merge( $this->getStarterShingle() );
$estimateItems = $estimateItems->merge( $this->getTearOff() );
$estimateItems = $estimateItems->merge( $this->getUnderlayment() );
$estimateItems = $estimateItems->merge( $this->getValleyMetal() );
and Collect()
$collectedItems = collect([
$this->getBoxVent(),
$this->getCoatings(),
$this->getCounterFlashing(),
$this->getDripEdge(),
$this->getFasteners(),
$this->getHeadwallFlashing(),
$this->getHipcap(),
$this->getIceShield(),
$this->getPipeFlashing(),
$this->getRidgecap(),
$this->getRidgeVentilation(),
$this->getSheathing(),
$this->getShingles(),
$this->getSidewallFlashing(),
$this->getSkylights(),
$this->getStarterShingle(),
$this->getTearOff(),
$this->getUnderlayment(),
$this->getValleyMetal(),
]);
There are only 4 database tables that have data pertaining to this "estimate" for this example. Ideally there would be 1 or all have data.
Why does Collection only return a maximum of 3, where as collect returns them all even if they're empty?
Am i doing something wrong to have the $estimateItems = new Collection();
only return 3, when theres 4 or more in database?
Here are the queries I am using.
private function getBoxVent() {
return ProposalBoxVent::where('proposalRecordID', $this->getProposalAPI())->get();
}
private function getCoatings() {
return ProposalCoatings::where('proposalRecordID', $this->getProposalAPI())->get();
}
If I use concat
instead of merge
I get the desired results.
Upvotes: 3
Views: 16755
Reputation: 50491
What you pass to collect()
is the array you want as the 'items' of the Collection. You are saying you want a Collection containing 18 items; it just happens to be that most of them are empty, but that doesn't matter to the array or Collection.
When you are merging you are actually merging the current items of the Collection with a new set of items. When merging it is possible that something is overwriting something else instead of adding to the Collection. Similar to how array_merge
works as that is what is happening internally. Eloquent Collections get keyed by 'id'.
It is possible to also try to use values
to reset the keys before merging:
$collection->merge($this->getValleyMetal()->values());
Upvotes: 1
Reputation: 18926
I would believe you are having problems with the merge method in Laravel
, merge will work differently if it is an associative array or an indexed array. If it's indexed, it should work as concat. Thou if it's associtive array it will try to merge it by key value base. Therefor i believe one of your underlying methods return something wrongfully.
With that said, if you are working with indexed arrays concat is better and quicker since it don't have to check. If you want to merge ['apple' => 'green']
with ['banana' => 'yellow']
into ['apple' => 'green', 'banana' => 'yellow']
you should use merge.
In regards to your question use concat
instead, if you are working with indexed arrays. Merge can also have bad performance in big sets.
$estimateItems = $estimateItems->concat($this->getBoxVent());
Upvotes: 2