merging collections grouped multiple times - laravel

I have a collection grouped (multiple times) like this:
Illuminate\Support\Collection {#1883 ▼
#items: array:1 [▼
57082 => Illuminate\Support\Collection {#1885 ▼
#items: array:1 [▼
"07-2021" => Illuminate\Database\Eloquent\Collection {#1863 ▼
#items: array:1 [▼
343 => Illuminate\Database\Eloquent\Collection {#1864 ▼
#items: array:1 [▶]
}
]
}
]
}
]
}
I have another collection that could have same values or not, and I need to merge these 2 collections with merged elements.
I tried with this, without success (I lose first "group"):
$fstCollection = $fstCollection->mapWithKeys(function ($items, $key) use ($sndCollection) {
return $sndCollection->get($key) ? $items->merge($sndCollection->get($key)) : $items;
});

I'm expecting your are loosing the key, by using mapWithKeys() wrong, in general that method is used, by returning an associative array, representing the key to map to and the value.
So changing the closure logic to the following, will keep the first group.
$collection = $sndCollection->get($key) ? $items->merge($sndCollection->get($key)) : $items;
return [$key => $collection];
Alternatively, just using map() will solve your problem, map() preserves the keys.
$fstCollection = $fstCollection->map(function ($items, $key) use ($sndCollection) {
return $sndCollection->get($key) ? $items->merge($sndCollection->get($key)) : $items;
});

Related

UpdateorInsert method in dynamic column cominig from array

I have some misunderstanding with the UpdateOrInsert helper with the DB
DB::table('table')
->updateOrInsert( );
}
I have a dynamic collection structured like this:
^ Illuminate\Support\Collection {#1534 ▼
#items: array:9 [▼
"it-IT" => array:1 [▶]
"cs-CZ" => array:1 [▶]
"de-DE" => array:1 [▶]
"en-GB" => array:1 [▶]
"en-US" => array:1 [▶]
"es-ES" => array:1 [▶]
"fr-FR" => array:1 [▶]
"ko-KR" => array:1 [▶]
"sk-SK" => array:1 [▶]
]
I would like to use the it-IT array as reference and Update the other languages or Insert a new line if the it-IT string don't exist.
This Collection comes from an array, I transform it in collectio just for use the chunk(); function.
The problem is, after a lot of tries, using in the correct way the UpdateOrInsert.
Cause, I undestand that I need to separe the reference with the rest, so I split the collection in two collection:
$coll = collect($array);
$chunks = $coll->chunk(500);
$refcol = collect($refArr);
$refchunks = $refcol->chunk(500);
foreach ($chunks as $chunk)
{
DB::table('dictionaries')
->updateOrInsert($refchunks->toArray(),$chunk->toArray() );
}
But this is not enought cause when it start to upgrade the data inside the database i get a strange query error:
select exists(select * from `dictionaries` where ((`1` = stringa di riferimento ))) as `exists`
so I think I have to split the collection in all languages collection, but the number and the languages are not always the same.
How can I do a foreach inside the UpdateOrInsert?
I have tried olso to using the Model way
Dictionary Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Dictionary extends Model
{
protected $primaryKey = null;
public $incrementing = false;
public $timestamps = false;
}
But when I perform the save() but if the it-IT string already exist it go in exception.
I tell to my self "Never give up" so I tried a thing like this:
try{
Dictionary::save();
} chatch (\Exception $e){
Dictionary::update();
}
But it save me the string like { 1: 'string in correct column'} and update method doesn't work.
Any way to help me?

Is there a way to only return the ID from this Laravel Query

I have run a query to get my specific needs but it's returning a whole bunch of array,
Is there a way to get only the specific column i needed?
This is what i am trying
$datas = DB::table('tableA')
->select('tableA.id')
->rightJoin('tableB','tableA.id','=','tableB.tableAt_id')
->where('tableB.active',1)
->whereIn('tableB.status',$myArray)
->get();
and the output is
Illuminate\Support\Collection {#1349 ▼
#items: array:221 [▼
0 => {#1327 ▼
+"id": 2020010201
}
1 => {#1346 ▼
+"id": 2020010202
}
2 => {#1343 ▼
+"id": 2020011501
}
I only want the ID. i tried toArray() but its the same
Use pluck.
Your code should be.
$datas = DB::table('tableA')
->rightJoin('tableB','tableA.id','=','tableB.tableAt_id')
->where('tableB.active',1)
->whereIn('tableB.status',$myArray)
->pluck('tableA.id');
Read More about Pluck Method

How to transpose this into an array?

I am trying to transpose a Collection into an array. I'm not sure what's the method to do this. I think it's due to my lack of understanding in the eloquent operators/commands. I've been trying with map but had not made any headway.
Data
Collection {#911 ▼
#items: array:4 [▼
"HIGH" => Collection {#902 ▼
#items: array:2 [▼
0 => Finding {#680 ▶}
1 => Finding {#681 ▶}
]
}
"MEDIUM" => Collection {#903 ▶}
"LOW" => Collection {#904 ▶}
"INFO" => Collection {#905 ▶}
]
}
I would like to transpose this into an array ['HIGH' => 2, 'MEDIUM' => 1, 'LOW' => 13 ...]
I tried to apply a map but it's not giving me what i want. (tried applying the below)
... ->map (function ($risk) { return $risk[0]; });
Looking for tips on learning about these map operators and also how to transpose the Collection result above. Any help will be the most welcome!
Use toArray function to convert the collection to the array
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toArray();
Hope this link helps you.
https://laravel.com/docs/5.7/collections#method-toarray

Get relation of relation

I'm trying to get the comments of the links with laravel relationship, the comments of links return normally, but I don't know how to get it in view or dd(), how can I do it?
Controller:
$page = Page::where('friendly_url', $id)
->select('id', 'photo', 'friendly_url', 'name', 'description', 'followers', 'links', 'tag_id', 'links_clicks')
->with('ptag', 'links', 'links.comments', 'links.tag')
->with(['links.comments.user' => function($query) {
$query->select('id', 'name', 'lastname');
}])->with(['links.comments.userProfile' => function($query) {
$query->select('id', 'photo');
}])->first();
dd($page->getRelation('links')
Collection {#301 ▼
#items: array:2 [▼
0 => Link {#307 ▼
#relations: array:2 [▼
"comments" => Collection {#316 ▼
#items: array:1 [▶]
"tag" => Tag {#322 ▶}
]
dd($page->getRelation('links')->getRelation('comments'))
BadMethodCallException
Method getRelation does not exist.
dd($page->getRelation('links')->comments)
Exception
Property [comments] does not exist on this collection instance.
EDIT:
I want to show the attributes of comment and comment.user, how I can do it?
foreach($page->getRelation('links')->pluck('comments') as $comment) {
dd($comment);
}
Collection {#327 ▼
#items: array:1 [▼
0 => Comment {#325 ▼
#attributes: array:5 [▼
"id" => 3
"content" => "teste"
"link_id" => 1
"user_id" => 1
"created_at" => "2018-01-11 00:47:32"
]
#relations: array:2 [▼
"user" => User {#330 ▼
#attributes: array:3 [▼
"id" => 1
"name" => "Halysson"
"lastname" => "Teves dos Santos"
]
}
"userProfile" => UserProfile {#326 ▶}
]
Try this-
foreach($page->links as $link){
$comments = $link->comments;
}
You should define relations first on relevent models and then using 'with' function can load models with relations OR a relation can be called directly by single model see documentation for further details
eg: you have defined a relation for user to phone, as user has a phone, one to one relation. in user model define a relation like
public function phone()
{
return $this->hasOne('App\Phone');
}
now to call this relation on user model instance.
$user = User::find(1);
dd($user->phone);
Because you're using the select() method, you also need to include all the foreign keys in it to allow Eloquent to be able to load these relationships.
But since you just start using Laravel, I'd recommend you to just remove select() method from this complex query.
If you want the links of a page :
$page->links
if you want all the comments of a page :
$page->links->pluck('comments')
that's it :)

Laravel 5.3 convert query builder to LengthAwarePaginator

I need to use switch cases to add constraints to the query I need to run. I need it to work with pagination, I tried this:
$albums = Album::with(array(
'images' => function ($query) {
$query->orderBy('order', 'asc');
}
))
->where('votes.votable_type','App\Models\Album')
->groupBy('albums.id');
$albums->published()->orderBy('created_at', 'desc')->paginate(30);
dd($albums);
and I get
Builder {#361 ▼
#query: Builder {#350 ▶}
#model: Album {#351 ▶}
#eagerLoad: array:2 [▶]
#macros: array:5 [▶]
#onDelete: Closure {#364 ▶}
#passthru: array:11 [▶]
#scopes: array:1 [▶]
#removedScopes: []
}
If I run
$albums = Album::with(array(
'images' => function ($query) {
$query->orderBy('order', 'asc');
}
))
->where('votes.votable_type','App\Models\Album')
->groupBy('albums.id')
->published()->orderBy('created_at', 'desc')->paginate(30);
dd($albums);
I get
LengthAwarePaginator {#467 ▼
#total: 97
#lastPage: 4
#items: Collection {#872 ▶}
#perPage: 30
#currentPage: 1
#path: "http://images.dev"
#query: []
#fragment: null
#pageName: "page"
}
why is there difference between these two approaches? I need to use first approach to be able to add constraints using switch case, I can't do that using second approach. But with first approach I do not get LengthAwarePaginator, how to fix it so that I get that?
You should redeclare the variable $albums if you wish it to be saved to this variable. Change this:
$albums->published()->orderBy('created_at', 'desc')->paginate(30);
To:
$albums = $albums->published()->orderBy('created_at', 'desc')->paginate(30);

Resources