Using Pivot relations in laravel - laravel

I've the following tables:
1.institute_codes
id
institute_id
course_id
code
1
3
45
ABCD
2.code_claims
id
code_id
user_id
approved
1
1
4
0
The institute_codes and code_claims are pivot tables. I want to retrieve users details based on the user_id column in code_claims and the course information which corresponds to the used code(code_id in code_claims table).
I've the following relationships till now:
class InstituteCode extends Pivot
{
use HasFactory;
protected $table = ['institute_codes'];
public function users()
{
return $this->belongsToMany(User::class, 'code_claims', 'code_id');
}
}
class User extends Model
{
public function codes()
{
return $this->belongsToMany(InstituteCode::class, 'code_claims');
}
}
Any help would be appreciated. Thanks.

So what exactly is your question here? :)
Your relationships are all messed up. I would read into the Laravel documentation first on relationships.
A basic has many / belongs to relationship is important, but also this one might be very interesting in your situation:
https://laravel.com/docs/9.x/eloquent-relationships#has-many-through
Also take note of the foreign key conventions below it.
One important tip is that the BelongsTo relation should always go in the model of the table with the foreign key (f.e. user_id). This way you can not go wrong.

Related

Laravel eloquent relationships with pivot table

Hello I have two models User and Car and a pivot table user_car which has two columns user_id and car_id, the combination of the two columns is always unique. Any user can have many cars and one car is assigned to only one user
In the User model I have this
public function cars()
{
return $this->belongsToMany('App\Car', 'user_car');
}
In the Car model I have this
public function user()
{
return $this->belongsToMany(
'App\User', 'user_car', 'car_id', 'user_id'
);
}
$user->cars
returns all the cars for the user as collection which is fine, but I want
$car->user
returns also collection which is only one user. I do not want collection, I want for example to get the user id like this
$car->user->id
Please use laravel default naming convention like alphabetically car_user so that you can follow along. Also it's not a many to many relationship as you've stated in your case it's a one to many relationship. A many to many relationship example something like an author can have many books published and a book can have many authors behind it so in a database table it would be like author_id and book_id in a table
Author_Id | book_id |
1 2
1 1
so in your case it would be like
class User {
public function cars()
{
return $this->hasMany('App\Car');
}
}
make sure you have user_id field in your cars table
and in your Car
class Car{
public function user()
{
return $this->belongsTo('App\User');
}
}
so that you can query it up like
$user = User::first();
$user->car->car_name ;
or when you start w/ car
// to pluck the specific car
$car = Car::find(3);
$car->user->full_name or owner depends upon you

Laravel One-to-Many and One-To-One relationship between the same tables

I have 2 tables:
Tourists,
Tours. (and corresponding models Tourist, Tour).
I have successfully set up many-to-many relationship between them. When I
$tour->tourists()->attach($tourist);
It creates a new record in a table Tour_Tourists. (tour_id, tourist_id, created_at, updated_at). It shows which tourists go with the particular tour.
Now I need to create another entity: Buyer. The buyer is one of the Tourists who pays for the Tour. Only one of the tourists belonging to the tour can be a Buyer.
I have set up one-to-one relations in both models:
<?php
namespace App;
class Tour extends Model
{
public function tourists() {
return $this->belongsToMany('App\Tourist')
->withTimestamps();
}
public function buyer() {
return $this->hasOne('App\Tourist')
->withTimestamps();
}
}
(and the same in Tourist model, except i changed 'App\Tourist' to 'App\Tour':
public function buyer() {
return $this->hasOne('App\Tour')
->withTimestamps();
)
but when I do:
$tour->buyer()->($tourist)
(where $tour and $tourist contain respective records from database), i get:
BadMethodCallException with message 'Call to undefined method Illuminate\Database\Query\Builder::withTimestamps()'
I have a feeling that I am doing it totally wrong. Can anyone just point out the direction I should move on to?
thank you.
withTimestamps() is a method used for belongsToMany only because it updates the created_at/updated_at fields of the pivot table. hasOne won't have this method.

Laravel 5.1 hasManyThrough Pivot table

I have model many to many relation like. I want to relate State and Category through pivot table CategoryNews.
Category model
class Category extends Model
{
public function news() {
return $this->belongsToMany('App\News');
}
}
News model
class News extends Model
{
public function categories()
{
return $this->belongsToMany('App\Category');
}
public function state()
{
return $this->belongsTo('App\State');
}
}
and the State model
class State extends Model
{
public function news() {
return $this->hasMany('App\News');
}
}
I want to select the news related to the state where cat_type=2(from category table)
i tried
$slide_news = State::whereHas('news.categories',function($query){ $query->where('categories.cat_type',2);})
->with(array('news'=>function($query){
$query->orderBy('created_at', 'desc');}
))->where('id',$id)->first();
but the cat_type filter is not working. I also tried hasManyThrough but i don't know how to implement it with Pivot Table
Please help
There is a Laravel 5.5 composer package that can perform multi-level relationships (deep)
Package:
https://github.com/staudenmeir/eloquent-has-many-deep
Example:
User → belongs to many → Role → belongs to many → Permission
class User extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function permissions()
{
return $this->hasManyDeep(
'App\Permission',
['role_user', 'App\Role', 'permission_role'], // Pivot tables/models starting from the Parent, which is the User
);
}
}
Example if foreign keys need to be defined:
https://github.com/staudenmeir/eloquent-has-many-deep/issues/7#issuecomment-431477943
To the moderators:
DO NOT DELETE MY ANSWER
It took me two god damn days to solve this issue, and I was so happy i found the solution that i want to let the world know
Notice that my answer was upvoted, yet you deleted it.
The question's title is regarding: hasManyThrough Pivot table for Laravel, and my answer gives just that, a solution to perform hasManyThrough equivalent on Pivot Tables
The question was 3 years old, and let's admit no one wants a solution specific to the question, because we've all got our own.
If I were you, I'd prefer a generic answer.

Laravel 5 Model relationships

I just want to make sure that I am handling my relationships correctly. In my database, I have foreign constraints set up. I have a users table and a departments table. A user can only be apart of one department. However, a department can have many users. So in User.php, I have
public function department()
{
return $this->belongsTo('App\Department');
}
And then in Department.php I have
public function user()
{
return $this->hasMany('App\User');
}
Does this represent the relationship I am after?
Thanks
Yes, this is correct for a one-to-many relationship.
The only thing I would change is user() to users() as there are "many" users.
Lastly, just make sure that in you users table you have a column called department_id, otherwise you will have to tell laravel explicitly which column name you're after.
Hope this helps!

Laravel - Pivot table for three models - how to insert related models?

I have three models with Many to Many relationships: User, Activity, Product.
The tables look like id, name. And in the each model there are functions, for example, in User model:
public function activities()
{
return $this->belongsToMany('Activity');
}
public function products()
{
return $this->belongsToMany('Product');
}
The pivot table User_activity_product is:
id, user_id, activity_id, product_id. The goal is to get data like: User->activity->products.
Is it possible to organize such relations in this way? And how to update this pivot table?
First I suggest you rename the pivot table to activity_product_user so it complies with Eloquent naming convention what makes the life easier (and my example will use that name).
You need to define the relations like this:
// User model
public function activities()
{
return $this->belongsToMany('Activity', 'activity_product_user');
}
public function products()
{
return $this->belongsToMany('Product', 'activity_product_user');
}
Then you can fetch related models:
$user->activities; // collection of Activity models
$user->activities->find($id); // Activity model fetched from the collection
$user->activities()->find($id); // Activity model fetched from the db
$user->activities->find($id)->products; // collection of Product models related to given Activity
// but not necessarily related in any way to the User
$user->activities->find($id)->products()->wherePivot('user_id', $user->id)->get();
// collection of Product models related to both Activity and User
You can simplify working with such relation by setting up custom Pivot model, helper relation for the last line etc.
For attaching the easiest way should be passing the 3rd key as a parameter like this:
$user->activities()->attach($activityIdOrModel, ['product_id' => $productId]);
So it requires some additional code to make it perfect, but it's feasible.
The solution was found with some changes.
In the models relationships look like:
// User model
public function activities()
{
return $this->belongsToMany('Activity', 'user_activity_product', 'user_id', 'activity_id')->withPivot('product_id');
}
public function products()
{
return $this->belongsToMany('Product', 'user_activity_product', 'user_id', 'product_id')->withPivot('activity_id');
}
To update pivot table:
$user->products()->save($product, array('activity_id' => $activity->id));
- where product and activity ids I get from Input.
And, for example, to check if "user -> some activity -> some product is already exists":
if ($company->activities->find($activity_id)->products()->where('product_id', '=', $product_id)->wherePivot('company_id', $company_id)->get()->count() > 0) {
// code...
}
I think it needs improvements but it works for me now.

Resources