Laravel eloquent relationship and view - laravel

I'm trying to show a structure using as example the tables showed in this thread:
Laravel Eloquent Filter By Column of Relationship
Using this I would like to show in one page (index.blade.php for example) something like this:
Category 1
Post1.Category1
Post2.Category1
Category 2
Post1.Category2
Post2.Category2
Post3.Category2
Post4.Category2
Category 3
Post1.Category3
I don't know what exactly which arrays to I need to pass from Controller.
I can get the list of Categories but how the post for each category???
Thanks
Any idea

You just need to pass in the Categories with their Posts. It's pretty straightforward.
Controller
$categories = Category::with('posts')->get();
return View::make('some.view')->with('categories', $categories);
View
#foreach($categories as $category)
{{{ $category->name }}}
#foreach($category->posts as $post)
{{{ $post->name }}}.{{{ $category->name }}}
#endforeach
#endforeach

Related

Laravel eloquent "with" the easy way

I have posted a related question a few hours ago but I can not understand why Laravel eloquent is so complicated... once again I read many posts on the subject and not one gave me the solution to a very simple request.
Here is the simple example where a post belongs to one article and one user only. So the relations are defined as below in the Post model:
public function article()
{
return $this->belongsTo(Article::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
I am quite new to Laravel eloquent... so I simply want to display a list of all the posts with their id, comment and related user name and article title as per relation defined in the model above. I believe that is quite simple and I just learned the "with" today.
So in the PostController, I have:
$posts = Post::orderBy($sortField,$sortOrder)
->with(['article','user'])
->get();
This gives me a collection with all the posts.
First question, do I have to manipulate the 2 related fields in such a way that they become easily accessible in the list view below? Or can I avoid this in controller in anyway by putting it in the query?
foreach ($posts as $post) {
$post->article = $post->article()->pluck('article');
$post->user = $post->user()->pluck('name');
}
In the above, the field $post->article lists all the article titles in an array (article field).
If I add [0] at the end, I get the first element of the array.
If I use [post->article_id] I get the wrong related title.
So nothing works the way I want... why is it so complicated???
Ultimately, here is what I need to do in the list view.
#foreach ($posts as $post)
<p>{{ $post->id }} : {{ $post->comment }} by {{ $post->name }} from article {{ $post->article }}</p>
#endforeach
By doing the query in query builder instead, I get what I want immediately... so how to do the same in eloquent?
$users = DB::table('posts')
->join('articles', 'articles.id', '=', 'posts.user_id')
->join('users', 'users.id', '=', 'posts.user_id')
->select('users.*', 'articles.article', 'users.name')
->get();
It is not clear what is making you misunderstand it, so here is an explanation.
First of all, you have two belongsTo relations user & article in your post model.
When you run this
$posts = Post::orderBy($sortField,$sortOrder)
->with(['article','user'])
->get();
You get a collection of Posts and with the article and the user in the attributes $post->article & $post->user respectively. That queryBuild will launch 3 queries, one for the posts, one for the articles and one final for the users.
Now, in your blade, you want to access the attribute article in your Article model wich is inside the Post model so you do it like this:
#foreach ($posts as $post)
.... from article {{ $post->article->article }}</p>
#endforeach
Notes: When you call $post->article() you get a query builder, so you follow it with a
first() => instance of a model / null
get() => Collection of instance of a model or empty collection
pluck() => array of the attribute plucked
value() => the value of the first element as if you used pluck
... (there are other ways to get results)
When you call $post->article without parenthesis, it will run :
first() if the relation is a belongsTo
get() if the relation is belongsToMany or HasMany or....
OR
It will give you the attribute if already fetched (either a collection or a model instance).
So, since you used with('article') in the first query (already fetched), $post->article will return an instance of the model Article and no new query will be run.

How to display two models data in lavavel blade view selected by with method

I have selected data from two models by with() method and now I want to display these Two models' record in view, how can I do this.
$posts=Post::where('slug','=',Str::lower($id))->with('comment')->first();
In your controller use this
$posts=Post::where('slug','=',Str::lower($id))->get();
return view('view.name',compact('posts');
Lets try this in your blade
#foreach($posts as $val)
{{$val->comment()->id}}
#endforeach
In controller
return view('view.name', ['posts' => $posts]);
In view
#foreach($posts as $post)
//do something
#endforeach

How to join pivot table in laravel

I have 3 tables like this to show all the categories that each story in it. How to make it show all category use join 3 tables. Should i use join or query in view/blade
catogory model
story model
view/blade
structure category
structure story
structure pivot tables
Thank you for the update, given the above, in your Controller I'm assuming you are calling something like Story::all(), you are going to want to eager load the categories with $data = Story::with('categories')->get(), then in your blade file you can loop through the categories and print out the name fields with
#foreach($data as $story)
{{ $story->name }}
#foreach($story->categories as $category)
{{ $category->name }}
#endforach
#endforeach
You can add any additional markup that you need.

Retrieving data from belongsToMany relationship in Laravel

I have some problems with getting data from my relationship. I need the tags of some domains.
$domains = Domains::where('customer_id', Auth::user()->customers_id)->get();
There are all the domains I need. On my Domains model I have this belongsToMany relation to my pivot table.
public function tags() {
return $this->belongsToMany('App\Models\Tags_Domains', 'domain_tag', 'domains_id', 'tags_id');
}
I was able to get all the datas from my relation with this:
dd($domains[0]->tags);
That gave me all the data I wanted but only for the very first domain. But I want this for every domain, to pass this new array to my Blade template. I tried many things out but couldn't make it work. ( $collection error, trying to get properly of non-object ... )
Can someone help me there?
Controller Code:
$domains = Domains::where('customer_id', Auth::user()->customers_id)->get();
return view('defaultLayout.domains.tagsdelete', [
'domains' => $domains
]);
This is because you use $domains[0] and you get the first domain.
You must loop through them:
foreach($domains as $domain) {
foreach($domain->tags as $tag) {
var_dump($tag);
}
}
Edit:
If you need the tags in your view here is how:
#foreach($domains as $domain)
<p>{{ $domain->name }}</p> //where name could be any field that $domain has
#foreach($domain->tags as $tag)
<p>{{ $tag->name }}</p> //where name could be any field that $tag has
#endforeach
#endforeach
Glad I was helpful :)

How to query data from a pivot table and display it using blade?

I am trying to query data from my pivot table and display it on my view
My View
#foreach ($catalog_downloads as $catalog_download)
<td>
<?php $frequencies = $catalog_download->export_frequencies()->get(); ?>
{{{ $frequencies }}}
</td>
#endforeach
When I do {{{ $frequencies }}} I got this :
[{"id":1,"name":"Semi Annual","created_at":"2015-01-14 15:44:59","updated_at":"2015-01-14 15:44:59","pivot":{"catalog_download_id":104,"export_frequency_id":1}},{"id":2,"name":"Quaterly","created_at":"2015-01-14 15:45:06","updated_at":"2015-01-14 15:45:06","pivot":{"catalog_download_id":104,"export_frequency_id":2}},{"id":3,"name":"Monthly","created_at":"2015-01-14 15:45:13","updated_at":"2015-01-14 15:45:13","pivot":{"catalog_download_id":104,"export_frequency_id":3}}]
But I don't want that. I want only the name.
So I did this {{{ $frequencies->name or '' }}} and now nothing come up at all. :(
More details
Here is how I define my relation.
public function export_frequencies(){
return $this->belongsToMany('ExportFrequency','export_frequency_catalog_download','catalog_download_id','export_frequency_id');
}
Can someone tell me what did I do wrong ?
By default, Laravel only selects the two foreign key from the pivot table. To change that add withPivot to your relationship definition:
public function export_frequencies(){
return $this->belongsToMany('Frequency')->withPivot('name');
});
Then you can access it through the pivot object:
#foreach($frequencies as $frequency)
{{ $frequency->pivot->name }}
#endforeach
Edit
I guess I've been confused by your question title. If you just want to display data from ExportFrequency you don't need withPivot and you can simply do this:
#foreach($frequencies as $frequency)
{{ $frequency->name }}
#endforeach

Resources