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;
});
Related
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', ...);
In a Post model I have:
public function tags()
{
return $this->morphToMany(\App\Models\Tag::class, 'taggable');
}
But when I then do:
$posts = Post::all();
$posts->tags()->detach();
I get
Method Illuminate\Database\Eloquent\Collection::inputs does not exist.
Based on your code, it seems like you're trying to remove all the tags from all the existing posts in your application.
If this is what you're trying to do, then follow #A.A Noman comment: you should detach them by iterating the collection, one by one.
Another option is to just clear the intermediate table containing the relations.
If what you're trying to do here is detaching all the tags from a single Post, you can search the post and then detach all the tags:
$post = Post::find($id);
$post->tags()->detach();
UPDATE
To iterate the collection and remove all the Tags from all the Posts:
$posts = Post::all();
foreach ($posts as $post) {
$post->tags()->detach();
}
Use Laravel's with()
https://laravel.com/docs/8.x/eloquent-relationships
To bring the tags related to this collection
Example:
$posts = Post::with('tags');
$posts->tags()->detach();
Likewise, if you want to remove a particular entity relationship from the pivot table, you can use the detach method.
For example, if you want to remove a certain author from a book, you can do so.
$book->authors()->detach($authorId);
Or you can pass multiple IDs as an array.
$book->authors()->detach([4, 5, 8]);
Or, if you want to remove all authors from a book, use detach without passing any arguments.
$book->authors()->detach();
I have table with many to many relationship.
User many to many Permission
I already define many to many relationship on both model, and create the pivot table also.
What I want is get all user which contain permission name
What I have done so far is
User::all()->permissions->contains('name', 'access.backend.admin')->get();
But it give me
Undefined property: Illuminate\Database\Eloquent\Collection::$permissions on line 1
What wrong with my code?
User::All() returns a collection not model object. You have iterate over the collection to get the model object and use ->permissions().
For exapmle:
$users = User::all();
foreach ($users as $user) {
$user->permissions->contains('name', 'access.backend.admin'); // returns boolean
}
Or you can get a single model from DB as:
$user = User::first();
$user->permissions->contains('name', 'access.backend.admin'); // returns boolean
Update 1
To get users which contain desired permission use filter() method as:
$filtered_users = $users->filter(function ($user) {
if ($user->permissions->contains('name', 'access.backend.admin')) {
return $user;
}
});
Update 2
You can also write a query which returns the desired result as:
$filtered_users = User::whereHas('permissions', function($q) {
$q->where('name', 'access.backend.admin');
})->get()
I have a similar case of questions and tags, they have many to many relationship.
So when i have to fetch all question with a particular tag then i do this
$tag = Tag::where('name','laravel')->get()->first();
I first retrieved the Tag model with name laravel.
and then retrieved all questions having tag laravel.
$questions = $tag->questions;
Similarly you can do this
$permission = Permission::where('name','access.backend.admin')->get()->first();
$users = $permission->users;
I know that we can insert array in Session as Session::push('person.name','torres') but how to keep laravel collection object such as $product = Product::all();,as like Session::put('product',$product);.Ho wto achieve this?
You can put any data inside the session, including objects. Seeing as a Collection is just an object, you can do the same.
For example:
$products = Product::all();
Session::put('products', $products);
dd(Session::get('products'));
Should echo out the collection.
You should convert it to a plain array, then convert them back to models:
Storing in the session
$products = Product::all()->map(function ($product) {
return $product->getAttributes();
})->all();
Session::put('products', $products);
Retrieving from the session
$products = Product::hydrate(Session::get('products'));
You can see an example of this method here.
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.