I solver this by this code
$service_list = Service::all();
$services = [];
foreach ($service_list as $item){
$services[$item['id']] = $item['name'];
}
but how to do that using php_array functions?
its for dropdown select
Not sure why you have to use PHPs built in array methods but we have pluck on the Query Builder and Collection class.
$services = Service::pluck('name', 'id');
// $services->all(); // for the actual array contained
This will only select the name and id in the query and give you a Collection keyed by the id only containing the name field.
$services = Service::all();
$services_array = $services->pluck('name', 'id')->all();
If you already have your collection of models (code above has queried for every field and hydrated models with the result) you can use pluck on the Collection to achieve the same result (though less efficient as it had to query for all fields, hydrate models, then pull those 2 fields from them)
Laravel 5.5 Docs - Query Builder - Retrieving Results
Laravel 5.5 Docs - Collections - pluck method
Use toArray() to convert the collection to an array, then use array_combine() to create an associative array from that.
$service_list = Service::all()->toArray();
$services = array_combine(array_column($service_list, 'id'), array_column($service_list, 'name'));
$service_list = Service::all()->toArray();
all() will return a collection. The collection supports a toArray() method
Related
I want to combine two data search results into one array, I use array_merge but there is an array_merge() error:
Argument # 1 is not an array
How to turn $vendor's eloquent results into an array and combine it with $plucked?
$vendor = Vendor::find($id);
$vendor_detail = VendorDetail::where('vendor_id',$id)->get();
$plucked = $vendor_detail->pluck('vendor_profile_value','vendor_profile_name');
$coba = array_merge($vendor,$plucked);
$plucked already an array
I think the problem here is that $vendor is not yet an array
You could do it like this:
$vendor = Vendor::find($id);
$vendor_details = VendorDetail
::select('vendor_profile_value', 'vendor_profile_name')
->where('vendor_id', $id)
->get()
->toArray();
$coba = array_merge($vendor,$vendor_details);
The get() method execute the query returning a Collection instance, in which you can call the toArray() method.
Side note
As far as I can see, you could make use of relationships and eager loading.
If you have a one-to-many relationship defined like this in your Vendor model:
public function details()
{
return $this->hasMany(VendorDetails::class);
}
Then, you could eager load the relationship like this:
$vendor = Vendor::with('details')->find($id);
// ^^^^^^^^^^^^^^
You could even just load the wanted fields:
$vendor = Vendor::with('details:vendor_profile_value,vendor_profile_name')
->find($id);
Then, your object will have a new attribute called "details" containing the related objects (or a collection of the limited selected fields).
You can convert the $vendor to an Array like below.
$vendor = Vendor::find($id)->toArray();
Suppose I have a query that, among other things, returns user id's, this query was built using DB::table()... rather than using the models, so, as a result, I got a collection with arrays for each retrieved row, something like this:
user_id | calculated_data
--------+----------------
1 | 123
2 | 111
3 | 222
... | ...
Supose I store this collection on a $data variable, of course if I do a foreach ($data as $d) { $d->user_id ... } will work.
But I want this query to return something more like what the ORM does, so instead user_ids, return User models so I can do, for example, a $data->user->name
Can this be even done? if so, how?
You can use the hydrate() function, it accepts an array of stdClass objects (or even associative arrays AFAIR) as input and returns a collection of Eloquent Models, so you can do things like this:
$result = DB::table('users')->take(10)->get();
$users = App\User::hydrate($result->all());
You can even get a collection of Eloquent Models directly from a RAW query with the fromQuery() function, i.e.:
$users = App\User::fromQuery('SELECT * FROM users WHERE id > ?', [2])
Update: If in your collection you don't have all the fields to hydrate a model, you can preload all the users you need with one query and modify your collection, i.e.:
$users = App\User::find($data->pluck('user_id'));
$data->transform(function($item) use($users) {
$item->user = $users->where('id', $item->user_id)->first()
return $item;
});
You need to use Eloquent to call value the "ORM way" I did not find anything related to the query builder in relation to ORM.
You could do something like this:
$flights = App\Flight::all();
foreach ($flights as $flight) {
echo $flight->name;
}
And in the ORM way you would get the user like this:
foreach ($flights as $flight) {
echo $flight->user->name;
}
Of course you would need to setup the correct relations.
// initial query will return collection of objects
$query = DB::table('user_something')
->join('users', 'users.id', 'user_something.user_id');
// You could cast it to the model query, by using fromSub.
// Make sure to alias a subquery same as the model's name,
// otherwise it would not be able to parse models data
User::fromSub($query, 'users');
// The most robust way is to get table name from the model
User::fromSub($query, User::make()->getTable());
I have two queries with Eloquent which I collect and merge and after i do sortByDesc but it's not sorting collection.
$f_games = collect(Game::with('fUser', 'sUser')->where('first_user_id', Auth::user()->id)>get());
$s_games = collect(Game::with('fUser', 'sUser')->where('second_user_id', Auth::user()->id)->get());
$response = $f_games->merge($s_games)->sortByDesc('id');
You can use values() at the end of sorting, as discussed in documentation
$gameCollection = collect($game);
$sorted = $gameCollection->sortByDesc('date');
return $sorted->values()->all();
In you case it should be
$response = $f_games->merge($s_games)->sortByDesc('id')->values();
There is no need to wrap in collect(), $f_games and $s_games will be collection without additional wrapping:
$f_games = Game::with('fUser', 'sUser')->where('first_user_id', Auth::user()->id)>get();
$s_games = Game::with('fUser', 'sUser')->where('second_user_id', Auth::user()->id)->get();
$response = $f_games->merge($s_games)->sortByDesc('id');
But the best way is:
$user_id = Auth::user()->id;
$f_s_games = Game::with('fUser', 'sUser')
->where('first_user_id', $user_id)
->orWhere('second_user_id',$user_id)
->orderBy('id', 'desc')
->get();
The sortByDesc method sorts the collection by field that belongs to some eloquent relation in your model.
If you are trying to sort collection with sortByDesc for model itself ( your current object of model), please user orderBy rather than sortByDesc
Example:
For model itself
{$collection_list = $this->model_name->orderBy('field_name','DESC')->get();}
For relations that will be lazy loaded in views
{$collection_list = $this->model_name->get()->sortBy('table_name.field_name', SORT_REGULAR, true);}
Note: sortByDesc internally called sortBy() with descending order,
true means Descending Order and false means Ascending Order.
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.
Here is my code$titles = DB::table('roles')->lists('title');
How Can I cast $titles from a Laravel 5 collection into an associative array?
Include the ID in the function, and call from the Model:
$titles = Role::lists('title', 'id')->toArray();
Or call directly as you are doing:
$titles = DB::table('roles')->lists('title', 'id');
In this case, in an select field for example, the id will be the option value.
A laravel collection has a toArray method that will return a numerically keyed array of the contents. (The indexes will be keyed exactly as they are in the collection. To reset them call values on the collection first.)
$titles = DB::table('roles')->lists('title');
$result = $titles->toArray();
For an associative array you will need to do this manually using something like this.
$titles = DB::table('roles')->lists('title', 'id');
$result = [];
foreach($titles as $title) {
// using an ID as the key and title as the value
$result[$title->id] = $title->title;
}