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.
Related
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');
As u guys can see in Image Above, i want to create referral_system that user can register and input referral_user from affiliate users.
And Referral_Code is unique for every user.
My Problem is I cant track Whom that code is.
My User Schema
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('referrer_id')->nullable();
$table->foreign('referrer_id')->references('id')->on('users');
$table->string('referral_code')->unique()->nullable();
$table->string('referred_by')->nullable();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
My User Model
public function referrer()
{
return $this->belongsTo(User::class);
}
public function referrals()
{
return $this->hasMany(User::class);
}
In My UserController
$referrer = User::where('name', auth()->user()->name)->first();
$user = new User();
$user->name = $request->name;
$user->referral_code = substr(uniqid(), 0, 8); // for unique id
$user->email = $request->email;
$user->referrer_id = $referrer ? $referrer->id : null;
$user->role = $request->role;
$user->password = bcrypt($request->password);
$user->save();
return response()->json([
'created' => true,
]);
Hope u guys will give me some idea and if u notice mistake in my code, pls correct me, I'll appreciate of all ur help.
Thanks...
I believe you're confusing Laravel relationships. hasOne, belongsTo, etc are not designed to be worked with in the same model. Basically what you're saying in Users model is that "User has a User where user_id = id" which makes no sense.
I have no idea how you've designed your sql tables, I recommend you to split your entities in distinct parts and have pivot tables which binds them: users, affiliates, referrals
- users table have : "id"
- affiliates table have: "id", "refferal_code"
- refferals table have : "id", "affiliate_id", "user_id", "refferal_code"
You tie a user with an affiliate through refferals table, through their IDs.
Then create relationships between those. You may want to read more about Eloquent relationships as well. Hope this answer helps you.
I have 2 table in my database.
first is table post
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->date('PostDate');
$table->string('PostTitle', 200);
$table->string('GroupID', 100)->nullable();
$table->integer('LanguageID')->default(1);
$table->timestamps();
});
second is table post_categories
Schema::create('post_categories', function (Blueprint $table) {
$table->integer('post_id');
$table->integer('category_id');
$table->timestamps();
});
Every time I store post data into database, it will stored as two rows.. because I have two active language. In my post_categories table, there has category_id column.. So, if the post data with id = 1 has 2 categories.. and the post data with id = 2 has 3 categories, it will create 5 rows in post_categories table.
But when I want to delete the post, I will check from the group ID first.. So, I will delete 2 rows too..
But the problem is, I can not delete the data in post_categories.. I have using foreach but the data won't be deleted..
This is my delete Controller:
public function destroy($id)
{
$post = Post::findOrFail($id);
Post::where('GroupID', $post->GroupID)->delete();
$postGroups = Post::where('GroupID', $post->GroupID)->get();
foreach ($postGroups as $postGroup) {
DB::table('post_categories')->where('post_id', $postGroup->id)->delete();
}
return response()->json([
"error" => "0",
"message" => "Success"
]);
}
I can delete all the post with same group ID, but I can not delete the post_categories data that has same post_id.
You've already chosen the answer, but in your case it's much better to use whereIn():
$post = Post::findOrFail($id);
$postGroups = Post::where('GroupID', $post->GroupID)->get();
DB::table('post_categories')->whereIn('post_id', $postGroups->pluck('id'))->delete();
Post::where('GroupID', $post->GroupID)->delete();
Delete the categories before deleting the post.
public function destroy($id)
{
$post = Post::findOrFail($id);
$postGroups = Post::where('GroupID', $post->GroupID)->get();
foreach ($postGroups as $postGroup) {
DB::table('post_categories')->where('post_id', $postGroup->id)->delete();
}
Post::where('GroupID', $post->GroupID)->delete();
return response()->json([
"error" => "0",
"message" => "Success"
]);
}
In order to have a better code experience, I recommend using a table structure like posts, posts_categories and posts_languages. This last one will contain the data regarding the content in multiple languages, and will be related to posts
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 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