Cannot access collection by properties Laravel 5.8 - php

So I have three different arrays with the same length in the request and below is how I combine them into one collection:
$inputs = collect();
$keys = collect(['id', 'username', 'email']);
foreach ($request['ids'] as $index => $id) {
$username = $request['usernames'][$index];
$email = $request['emails'][$index];
$inputs->push($keys->combine([$id, $username, $email]));
}
The result looks correct to me:
However, I cannot access the collection when I iterate over it:
foreach ($inputs as $input) {
dd($input->id); // Property [id] does not exist on this collection instance.
}
This is the result of dd($input):
Any pointers on this problem? (Another short way to combine the arrays into one collection will also be appreciated!)
Thank you.

It is a collection and you should get it like this: dd($input['id']).

You can combine arrays bt array_merge
array_merge($a1,$a2)
or collect
$c=collect([$arr1,$arr2])
then pluck if you want
$c->pluck('username')

Related

Laravel: Querying JSON column containing array, expecting similar results to "whereIn"

I have a database column called support_tags. This is a jsonb column containing a simple array that looks like:
[
"caring",
"budgets",
"careers_employment",
"addictions"
]
I am attempting to query this column using the following:
$services = \App\Models\Service::where("status", "accepted")->whereRaw("JSON_CONTAINS(support_tags, '" . json_encode($categories) . "')")->get();
This doesn't retrieve the results I am hoping for/expecting. If I send the following array:
[
"caring",
"smoking"
]
The results I get back are services that contain all array elements. I need this to work more like a whereIn, in that not all array values need to be present in the database column, but one or more. If anyone knows of a way to do this I'd be very grateful. Thanks.
you can use these eloquent methods: ->whereJsonContains() and ->orWhereJsonContains()
your query will be like this:
$services = \App\Models\Service::where("status", "accepted")
->where(function($query) {
$query->whereJsonContains('support_tags', 'smoking')
->orWhereJsonContains('support_tags', 'caring');
});
Just before I accept the other answer to this question, I thought it may be useful to share my implementation of this which is based on the accepted answer This does the trick:
$categories = request()->infoAdviceCategories;
$services = [];
if (count($categories)) {
$services = \App\Models\Service::where("status", "accepted")->whereJsonContains("support_tags", $categories[0]);
foreach ($categories as $category) {
if ($category !== $categories[0]) {
$services->orWhereJsonContains("support_tags", $category);
}
}
$services = $services->get();
}
return $services;

Laravel - Carry array through map

Let's say I have a model collection that I'm mapping through like this:
$alreadyImported = [];
$players = Players::whereNotIn('id', $alreadyImported)
->get()
->random(25)
->pluck('id');
$groups = $players->map(function ($item, $key) use ($alreadyImported) {
array_merge($alreadyImported, $item->id);
$group = [
'username' => $item['username'],
];
return $group;
});
// $groups is a pivot table with group and players
Why does my $globalList always start at []? How can I carry the already-merged $globalList to the next map iteration?
The player IDs does not matter. It's for show. I am looking to pass the array through the map iterations.
Just use pluck() to get IDs from the collection:
$ids = $players->pluck('id');
Or, if you just need IDs:
$ids = Players::where('banned', false)->pluck('id');
If you're going to add any other data, you don't need to merge it to some array or a collection because map() will create a new collection.
Finally, you don't need to use collect() because get() will return collection.

Extract all possible values of AR column in yii2

Several models in yii2 are bound to a database using ActiveRecords. I now want to have a list of all ids of this model. Say, all user IDs when the Model is called User.
Sure I could just fetch all models and iterate over them, much like
$ids = [];
$users = User::find()->all();
foreach ($users as $user) {
$ids[] = $user->id;
}
But I feel there should be an easier way... Thanks in advance.
If you want to stay in ActiveRecord then this accomplishes the same thing:
$ids = User::find()->select('id')->column();
This returns array:
$ids = (new \yii\db\Query)->select('id')->from(User::tableName())->all();

Laravel collection manipulation

I have User model that has 2 fields: email and id
I have this query:
$users = User::all()->get();
the result will be 3 User objects in a Collection
I want to see the result as the following:
[87 => 'user#gmail.com', 92 => 'admin#gmail.com', 10 => 'super#gmail.com']
id will be the key and email will be the value.
Is that possible via Collection class to implement? thanks
Try:
$users = User::pluck('email','id');
You can achieve like this,
$users = User::pluck("email","id");
pluck() -> You may also specify how you wish the resulting collection to be keyed:
There is alternative to do this(playing with collections),
$users = User::all()->get();
$users = $users->pluck("email","id");
Give it a try, this will work.
try this
$users = User::all();
$data = array();
foreach ($users as $key) {
$data[$key->id] = $key->email;
}
print_r($data);
Good luck...

Eloquent column list by key with array as values?

So I can do this with Eloquent:
$roles = DB::table('roles')->lists('title', 'name');
But is there a way to make Eloquent fetch an array of values for each distinct key instead of just one column?
For instance, something like the following:
$roles = DB::table('roles')->lists(['*', DB:raw('COALESCE(value, default_value)')], 'name');
You can use the keyBy method:
$roles = Role::all()->keyBy('name');
If you're not using Eloquent, you can create a collection on your own:
$roles = collect(DB::table('roles')->get())->keyBy('name');
If you're using Laravel 5.3+, the query builder now actually returns a collection, so there's no need to manually wrap it in a collection again:
$roles = DB::table('roles')->get()->keyBy('name');
If you need a key/value array, since Laravel 5.1 you can use pluck. This way you can indicate which attributes you want to use as a value and as a key.
$plucked = MyModel::all()->pluck(
'MyNameAttribute',
'MyIDAttribute'
);
return $plucked->all();
You will get an array as follow:
array:3 [▼
1 => "My MyNameAttribute value"
2 => "Lalalala"
3 => "Oh!"
]
You may try something like this:
$roles = array();
array_map(function($item) use (&$roles) {
$roles[$item->id] = (Array)$item; // object to array
}, DB::table('roles')->get());
If you want to get an Object instead of an Array as value then just remove the (Array).
Alternative: Using Eloquent model (Instead of DB::table):
$roles = array();
array_map(function($item) use (&$roles) {
$roles[$item['id']] = $item;
}, Role::all()->toArray());
Another Alternative: Using Collection::map() method:
$roles = array();
Role::all()->map(function($item) use(&$roles) {
$roles[$item->id] = $item->toArray();
});

Categories