Getting all items with another Eloquent query ID in Laravel - laravel

I have something like this:
$items = Item::whereIn("name", $request["names"])->get();
Now I want to get a list of shops that have any of those items. Something like this:
$shops = Shop::whereIn("item_id", $items)->get();
This does not work, because items is an eloquent collection (obviously). I could do some loop and get all the ids like this:
foreach ($items as $item){
$itemIds[] = $item
}
And then use it, but I feel there must be a cleaner way.
Any help?

Use ->pluck('id') and whereIn():
$items = Item::where('name', $request['names'])->get();
$shops = Shop::whereIn('item_id', $items->pluck('id'))->get();
Eloquent Collections have access to many of the same functions of Laravel's Collection Class:
https://laravel.com/docs/9.x/collections#available-methods
->pluck('id') will return an array of all items.id records, which you can then use to query via ->whereIn('item_id', ...);

Related

collections and eloquent results

I have a set of row returned from a function and stored in a variable called $topics. Each topic contains a set of articles. so for the variable $topics if we do $topics[0]->articles we get several articles, and if we do $topics[1]->articles we get another set of articles. What i want to do is to put all these articles in one variable lets call it $articles so that I can do operations such as
$articles->where('author', 'Jone Doe')->get();
I tried to do this:
$articles = new collection();
foreach( $topics as $topic) {
foreach( $topic->articles as $article)
$articles->push($article);
But this unfortunately destroys the actual structure of the articles. like I can't do $articles->translations where i use a translation package. but i can do $topics[0]->articles->translations. basically i want to get all the articles in one collection as if they were returned from doing something like
$articles = Article::all()->get();
Thanks
Just use the pluck method on your collection
$articles = $topics->pluck('articles');
And if you wish a 1-dimension articles collection
$articles = $topics->flatMap(function ($topic) {
return $topic->articles;
});

Can I put a collection or array into the where clause on laravel eloquent?

$collection=["c","a","f","h","j","o","k"]
$total_sums=Models::select('count')->whereIn('class',['c','a','f','h','j','o','k'])
->get()
->sum('count');
can I use variable $collection like this?
$total_sums=Models::select('count')->whereIn('class',[''.$collection.''])
->get()
->sum('count');
You can use both.
whereIn() accepts both Array and a Collection.
You just simply pass it as a second parameter.
$array = ["c","a","f","h","j","o","k"];
$collection = collect($array);
$total_sums=Models::select('count')->whereIn('class', $array)
->get()
->sum('count');
// works
$total_sums=Models::select('count')->whereIn('class', $collection)
->get()
->sum('count');
// also works!
No because $collection is already an array. When you try to concatenate it to a string, I believe your query will look like the following...
select count from models where class in ('Array');
What you probably actually want to do is...
->whereIn('class', $collection)

flattening joins in eloquent

If I wanted to JOIN two tables I could do this:
$books = App\Book::with('author')->get();
The problem with that is that the results are kinda nested. eg. If I wanted to get the DOB of the author I'd have to do this:
foreach ($books as $book) {
echo $book->author->dob;
}
But what if I, instead, wanted to be able to do this?:
foreach ($books as $book) {
echo $book->dob;
}
How might I go about doing that? I suppose there could be a conflict dob was a column in the book table and the author table and that doing author_dob would be better but let's assume there isn't a conflict.
I guess a view could do the trick but is there a way to do that in Laravel without having to create a view?
$books = DB::table('books')
->join('authors', 'authors.id', '=', 'books.author_id')->get()
Actually you can do the same using eloquent. This way, you'll have access to all functions and extra parameters in your Book model file
App\Book::join('authors', 'authors.id', '=', 'books.author_id')->get()
You might want to use leftJoin() instead of join()

Use Eloquent to attach array to query

I have a USER table, an ITEMS table, and a LIKES table. I'm randomly taking 9 items from the Items table (which is named 'categories') and I want to get an array of users which liked that item. I'm returning a JSON response so I can't use laravel's ORM relationships as far as I know. I want to be able to look through the results (with javascript) like so:
foreach item
item->price
....
foreach user
(this is how i wish to look through the users with js)
endforeach
endforeach
{{--Im trying to get an output that looks like so--}}
0: {
cost: 409
views: 0
...
user_like_id: {1,5,2,4,5}
}
EDIT: This is what I would like to attach the array to...
$likes = Category::orderByRaw("RAND()")
->leftJoin('likes', 'likes.item_id', '=', 'categories.id')
->take(9)
->get();
I'm relatively new to programming so please dont downnrate this question
Laravel provides in ways to make json from objects. The first and simplest is the eloquent toJson() method:
$likes = Category::orderByRaw("RAND()")
->leftJoin('likes', 'likes.item_id', '=', 'categories.id')
->take(9)
->get()
->toJson();
$likes is now json.
Second method:
If you return a model from a controller or a routecallback function, laravel returns it as json. So:
class MyController extends Controller{
public function getIndex(){
return Category::orderByRaw("RAND()")
->leftJoin('likes', 'likes.item_id', '=', 'categories.id')
->take(9)
->get();
}
}
This example returns a json response which is quite usefull!
I actually got exactly what I wanted with this:
$likes = Category::orderByRaw("RAND()")
->take(9)
->with(array('getLikes' => function($query)
{
$query->with('getUser');
}))
->get();
Works exactly how I want ito :) thanks for the suggestion tho

Laravel Create Collection of a certain Model and add Objects manually

I got a list of IDs and need to get a Collection (Let's say of the type "Book") and add Single Books to this Collection by Hand.
Example:
$ids = array(1,5,7,12);
$books = ???
foreach($ids as $id){
$books->add(Book::find($id)); }
Or is there a easier way to get what I want?
Thank you
You could write something like this I think:
$books = Book::whereIn('id', $ids)->get();
$books will be a Collection containing all your books.

Resources