I have set up the relationship and the models as below:
pivot table schema
Schema::create('friend_user', function(Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('friend_id')->unsigned();
$table->timestamps();
});
pivot table seeder (this defines two 'friendships' to which user '1' belongs one where user 1 is specified in the user_id and the second where user 1 is listed in the friend id):
$friend_user = array(
array(
'id' => 1,
'user_id' => 1,
'friend_id' => 3,
),
array(
'id' => 2,
'user_id' => 4,
'friend_id' => 1,
),
);
User model
public function friends()
{
return $this->belongsToMany('User', 'friend_user', 'user_id', 'friend_id');
}
This is as suggested by Taylor Otwell here: https://github.com/laravel/framework/issues/441
This all works but when I run the following command I get only one result:
foreach(Auth::user()->friends as $i) {
var_dump($i->id);
}
This returns the value '3' but not 4 as expected. I understand why this is happening (as the user_id is not the friend_id) but how can I get this to return a collection of all friends belonging to a user (ie all friendships) regardless of which end of the connection (user_id or friend_id) the user is?
Instead of creating two records use a new function.
public function friends()
{
return $this->belongsToMany('User', 'friend_user', 'user_id', 'friend_id');
}
// Same table, self referencing, but change the key order
public function theFriends()
{
return $this->belongsToMany('User', 'friend_user', 'friend_id', 'user_id');
}
//You can then call opposite record(s) using:
foreach( Auth::user()->theFriends as $theFriends )
I used this approach in my project so I can have better separation for organizing the results.
use this
public function friends()
{
return $this->belongsToMany('User', 'friend_user', 'user_id', 'friend_id')->orWhere('friend_id', $this->id);;
}
in this case you get one query and one record for each relation
Related
I want to get specific column from Model relation in Laravel, but the relation model returning empty array.
Eloquent Query
$medicines = Medicine::with(['weightage' => function($query) {
$query->select('name');
}])->get(['name', 'description']);
Medicine Modal
public function weightage()
{
return $this->hasMany('App\MedicineWeightage', 'medicine_id');
}
You always need to also select the primary and foreign keys of the table to make the relation work:
$medicines = Medicine::with(['weightage' => function($query) {
$query->select(['id', 'name', 'medicine_id']);
}])->get(['id', 'name', 'description']);
I have 2 tables that are named Resort and booking. in the booking table, there is a field named amount. I want to join these tables using with hasMany relation and get sum of the amount field in the booking table using with groupBy. can you please help me to solve this problem?
Thanks in Advance
Laravel Eloquent has the own withSum() method for avoiding "groupBy()" method.
For your case you can use something like this (you can modify for your needs):
// resorts with bookings and their summary prices
$data = Resort::select([
'id',
'name',
'image',
])
// ->orderBy('some_field', 'ASC')
->with(['bookings' => function($query) {
return $query->select([
'id',
'booking_id',
'price',
]);
}])
->withSum('bookings', 'price')
// ->where('resorts.some_field', '<=', 123)
->get();
// ->toArray();
But don't forget to have appropriate relation defined in your parent (Resort) model:
public function bookings() {
return $this->hasMany(Booking::class, 'resort_id', 'id');
}
Also you need to have "resort_id" foreign key defined in child's (Booking) migration:
$table->unsignedTinyInteger('resort_id')->nullable();
$table->foreign('resort_id')->references('id')
->on('resorts'); // ->onUpdate('cascade')->onDelete('cascade');
I have 4 Models:
Student
Tutor
Course
Admin
I am able to fetch all the students and tutors with their Ids.
I want to the admin to create Courses and store them in pivot Tables:
course_student
course_tutor
Yet, the relationships are not too clear for me. I assume that I need
belongsToMany
between Course and Student. The same goes for Tutor and Course am i right?
What is also not clear is, how can I select many values on the HTML side and submit them to the server.
E.g:
public function store(AdminCreateNewCourseRequest $request)
{
$this->authorize('create-course');
$course = new Course;
$course->name = $request->name;
$course->tutor_id = $request->tutor_id;
$course->student_id = $request->student_id;
$course->spoken_language = $request->spoken_language;
$course->description = $request->description;
$course->save();
What to do?
return redirect($course->path())
->with('flash', 'The course has been published');
}
Here is the AdminCreateNewCourseRequest
public function rules()
{
return [
'name' => 'required|unique:courses|max:60',
'tutor_id' => [
'required',
Rule::exists('tutors', 'id');
],
'student_id' => [
'required',
Rule::exists('students', 'id');
],
'spoken_language' => 'required',
'description' => 'required|max:255'
];
}
I might let the admin selects multiple tutors and students.
How can I accomplish this?
Many Thanks.
As i see, your common model is Course so firstable:
Add in your Course model the following:
public function students()
{
return $this->belongsToMany(Student::class);
}
public function tutors()
{
return $this->belongsToMany(Tutor::class);
}
Then, you need to create the pivot table for both classes ( Student and Tutor ):
Add this to your migrations file (for student and tutor respectively):
Schema::create('course_students', function (Blueprint $table) {
$table->increments('id');
$table->integer('course_id')->unsigned()->index();
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
$table->integer('student_id')->unsigned()->index();
$table->foreign('student_id')->references('id')->on('students')->onDelete('cascade');
});
Schema::create('course_tutors', function (Blueprint $table) {
$table->increments('id');
$table->integer('course_id')->unsigned()->index();
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
$table->integer('tutor_id')->unsigned()->index();
$table->foreign('tutor_id')->references('id')->on('tutors')->onDelete('cascade');
});
Please see the name of fields i am using and be sure you are using the same.
To get the students and tutors of a course you can do it by
$course = App\Course::find($id);
$students = $course->students;
$tutors = $course->tutors;
Hope this help!
By the way this is a very usefull Eloquent Relationships Cheat Sheet you can use to aproach this.
I have three tables: users, organizations, organization_user. organization_user is a pivot table for the many-to-many relationship between users and organizations. The many-to-many relationships have been setup correctly in the corresponding models.
I need to obtain all users who are not associated with a given organization. How should this be done using eloquent. Below is what I have tried, but it is returning no results:
public function associate_user($organization_id){
$data = [
'organization' => \App\Organization::find($organization_id),
'users' => \App\User::whereDoesntHave('organizations', function($query) use ($organization_id){
$query->where('organization_id', $organization_id);
})
];
return view('admin.associateUser', $data);
}
You are never actually executing the query.
You need to call get() at the end of the query builder.
public function associate_user($organization_id) {
$data = [
'organization' => \App\Organization::find($organization_id),
'users' => \App\User::whereDoesntHave('organizations', function($query) use ($organization_id){
$query->where('organization_id', $organization_id);
})->get(); // Add the call to get()
];
return view('admin.associateUser', data);
}
I'm not sure how to explain my problem but i'll give it a try.
I'm using Laravel 5 and i have 3 tables:
pages
languages
language_page
This is what my models look like:
Page model:
public function languages()
{
return $this->belongsToMany('App\Language', 'language_page')
->withPivot('title', 'content', 'slug', 'meta_title', 'meta_description')
->orderBy('main', 'desc');
}
Language Model:
public function pages()
{
return $this->belongsToMany('App\Page')
->withPivot('title', 'content', 'slug', 'meta_title', 'meta_description');
}
What i want to do return a record from the page table where language_id is a certain id, and where slug is a certain text.
This is what i got so far: EDIT:
Page::with(['languages' => function($q) use($language_id, $slug) {
$q->where('language_id', $language_id);
$q->wherePivot('slug', $slug);
}])
->first();
My problem: how can i add a where clause with the column slug (from the pivot table language_page) ?
i hope this makes any sense at all..
Eloquent's BelongsToMany class has a
wherePivot()
method that allows you applying WHERE clauses to pivot table directly, see:
https://github.com/laravel/framework/blob/5.1/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php#L111