Laravel sort and/or group from relationship - laravel

In livewire, I'm getting a collection of records ($testItems) from a many-many relation like:
---blade---
<livewire:test-items :test="$test"/>
---test model---
public function items ()
{
return $this->belongstoMany(item::class);
}
---livewire component---
render(){
$testItems = $this->test->items;
return view ('livewire.test-items',['testItems' => $testItems]);
}
---test-items livewire component blade---
#foreach ($testItems as $testItem)
<div> {{$testItem->question}}</div>
<div> {{$testItem->category->name}}</div>
<div> {{$testItem->answer}}</div>
#endforeach
Each item also has other fields like 'category' and I'd like to sort or group the display of these testItems in the component by category. What's the eloquent syntax for this?

Related

Hot to show the posts that have same category id in laravel livewire?

the livewire component is route bonded as:
Route::get('/post/{post}', Bycategory::class)->name('posts.by-category');
in-home view I want to click on the category name and get all posts with same category:
#foreach($post->categories as $category)
{{ $category->name }}
#endforeach
this is bycategory livewire class:
public Post $post;
public function render()
{
Post::with('categories')->where(function ($q){
$q->where('category_id', $this->post->categories()->id);
})->get());
return view('livewire.post.bycategory', compact('posts'))->layout('layouts.app');
}
the post and categories have many to many relations with the category_post table
but I get an error that there is not category_id in Post model;
the $this->post->categories()->id show the category id of that post;
As you mentioned that the the error above, it is clear that posts table does not have the category_id column and that is why you get this error. I think this is the right way to do this query
Post::with('categories' , function ($query) { $query->where('categories.id', $this->post->categories()->id);} )->get());

How to query data from laravel relationship using vue.js? [ laravel, vue ]

I want to query my data in relationship using vue.js and still, I cant make it work.
Also, I got an errors like below.
[Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined"
When I changed my code like this
<span v-for="user in users">
{{ user.address.city }}
</span>
And in my Controller
public function index(Request $request)
{
$query = Customers::with('address')
->with('purchases')
->paginate(10);
return CustomersResource::collection($query);
}
<div v-for="user in users">
<span v-if="user.address && user.address.name">{{ user.address.name }}</span>
</div>
Always check if your object exists before accessing it.
Add withDefault after your relationship.
public function address(){
return $this->belongsTo('App\Address','user_id','id')->withDefault([
'name' => '-'
]);
}
There is existing code that depends on the result of any Eloquent relationship to either be null, a Model instance, or a Collection of Model instances. However, the current functionality of the withDefault() method opens up the potential for returning an object that is not one of those three expected values.

Building complex Eloquent query using belongsToMany relationship, foreign table and whereIn()

In a Laravel 5 app, I have 5 tables - users, books, authors, followers and activity_feeds.
Users can follow authors and a book can have several authors.
When a book is made, an activity_feeds entry is made that references the book_id.
I need to build an eloquent query to get a collection of activity_feeds for each users, to iterate over in their home page activity feed.
My Book model includes
public function authors()
{
return $this->belongsToMany('App\Author')->withTimestamps();
}
The activity_stream table looks like this (with example data)
id (1)
user_id (3)
type (New Book)
book_id (18)
created_at etc
and my User controller includes
public function feedItems()
{
return $this->hasMany('App\ActivityFeed');
}
public function userFollowings()
{
return $this->belongsToMany('App\User', 'followers', 'follower_id', 'subject_id')->withTimestamps();
}
public function authorFollowings()
{
return $this->belongsToMany('App\Author', 'followers', 'follower_id', 'author_id')->withTimestamps();
}
My current query (which isn't working), contained in the User model is
public function getactivityFeedsAttribute()
{
$userFollowings = $this->userFollowings()->pluck('subject_id')->toArray();
$authorFollowings = $this->authorFollowings()->pluck('author_id')->toArray();
$userFeeds = ActivityFeed::whereIn('user_id', $userFollowings)
->orwhereIn('book_id', function($query){
$query->select('id')
->from(with(new Book)->getTable())
->whereHas->authors()
->whereIn('id', $authorFollowings);
})
->get();
return $userFeeds;
}
$userFollowings and $authorFollowings are working fine.
I'm not sure I'm using the correct syntax for data[book_id] to pluck the book id from the activity_feeds row, and I'm really not sure if I can nest a table look up or use $query like this.
It also seems VERY complicated. Am I might be missing something much more straight forward?
In the blade I am calling like this
#forelse ($user->activityFeeds as $activityFeed)
<div class="row">
<div class="col-2">
{{ $activityFeed->user->firstname }}
</div>
<div class="col-2">
{{ $activityFeed->type }}
</div>
</div>
<hr>
#empty
No activity yet
#endforelse
Which works if I just query 'ActivityFeed::whereIn('user_id', $userFollowings)'
I'll rewrite the query in an answer because comments aren't very legible.
public function getactivityFeedsAttribute()
{
$userFollowings = $this->userFollowings()->pluck('subject_id')->toArray();
$authorFollowings = $this->authorFollowings()->pluck('author_id')->toArray();
$books = Book::whereHas('authors', function ($query) use ($authorFollowings) {
// Have to be explicit about which id we're talking about
// or else it's gonna throw an error because it's ambiguous
$query->whereIn('authors.id', $authorFollowings);
})->pluck('id')->toArray();
$userFeeds = ActivityFeed::whereIn('user_id', $userFollowings)
->orwhereIn('book_id', $books)
->get();
return $userFeeds;
}

accessing collections within collections laravel 5

I have a table of "rosters" that's pretty much strictly foreign keys. It acceses the "schools" table, "courses" table, and "students" table. So essentially, a 'student' takes a 'course' at a 'school'. My RostersController has this
public function show($id)
{
$roster = Roster::where('course_id', $id);
return view('roster')->with('roster', $roster);
}
My Roster Model is:
public function students()
{
return $this->hasMany('App\Student');
}
My student Model is:
public function roster()
{
return $this->belongsTo('App\Roster');
}
my view is this:
#foreach ($roster as $child)
<p>{{$child->id}}</p>
<p>{{$child->students->first_name}}</p>
#endforeach
The rosters table just saves the student_id rather than all of the student's data that is already in the 'students' table. So i'm trying to access the students table from this relation but when i run this, it tells me that anything related to the students table is 'not on this collection'. I know that I could do things this way if i was working with a hasOne relationship, but how can i accomplish this with a hasMany to output the students table value in each row?
You should try this
public function show($id)
{
$roster = Roster::with('students')->where('course_id', $id);
return view('roster')->with('roster', $roster);
}
Try this
Roster.php
public function show($id)
{
$roster = Roster::with('students')->where('course_id', $id)->get(); // load the students
return view('roster')->with('roster', $roster);
}
On the view
#foreach ($roster as $child)
<p>{{$child->id}}</p>
<p>
<!-- Loop through the stundents since this returns an collection of students and not just one -->
#foreach($child->students as $student)
{{$student->first_name}} <br>
#endforeach
</p>
#endforeach
Check this for more information on eager loading
The $child->students is a collection. So, you need to use another foreach loop inside the first one.
Your code should look like this:
#foreach ($roster as $child)
<p>{{$child->id}}</p>
#foreach($child->students as $student)
<p>{{$student->first_name}}</p>
<p>{{$student->age}}</p>
<p>{{$sutdent->another_column_in_students_table}}</p>
#endforeach
<p>{{$child->any_other_column_in_roster_table_if_needed}}</p>
#endforeach
So, your first issue is, that
$roster = Roster::where('course_id', $id);
will just return a QueryBuilder instance, you have to use
$roster = Roster::where('course_id', $id)->get();
then for sure, students is a collection, you have to iterate over it like this:
#foreach ($child->students as $student)
{{ $student->yourProperty}} <br>
#endforeach
Update:
I saw you know already about that when to use get() in query laravel 5

Laravel Output 1 result from hasmany relationship

I have a hasmany relationship on my model and I'm trying to output just the one result, i have a product category which can display only one product image.
I have two tables.
1 = Product
2 = ProductPhotos
I've tried outputting the one photo like
#foreach($products as $product)
<img src="{{ $product->photos->first() }}">
#endforeach
I have the following relationship setup in my product model
public function photos()
{
return $this->hasMany('App\ProductPhoto', 'product_id');
}
but this doesnt work.
You're just missing the parenthesis for the method. It should be:
$product->photos()->first();
Which will allow Eloquent to access the photos method in the Product model.

Resources