Laravel, Eloquent table relating to itself through pivot table - php

I have users class (table):
id
username
And relations table:
user_id
subscribed_by
Idea: each User can subscribe for each other user.
Last variant was (don't work):
/* class User extends Eloquent ... */
public function followers() {
return $this->belongsToMany('User', 'rel_table')->withPivot('user_id');
}
public function following() {
return $this->belongsToMany('User', 'rel_table')->withPivot('subscribed_by');
}
Need help: how to set up this?

First, an advice, you should rename the fields in your pivot table follower_id and followed_id (or something like that). That's more clear.
Then you have to define relations like that :
public function followers() {
return $this->belongsToMany('User', 'rel_table', 'followed_id', 'follower_id');
}
public function following() {
return $this->belongsToMany('User', 'rel_table', 'follower_id', 'followed_id');
}
The withPivot method is used to define other attributes on the relation than the two foreign keys.

Related

Defining Laravel Relationship in Custom Primary Key and Foreign Key

I have 2 tables and It is One to One Relationship Model Type.
Students Table = id|nik|name|address. Accounts Table = id|nik|username|password.
In this case every student has one account and i took NIK as the $primaryKey in student model. How to define a relationship for that? Thanks in advance.
// Student Model
public function account()
{
return $this->hasOne(Account::class, 'nik', 'nik');
}
// Account Model
public function student()
{
return $this->belongsTo(Student::class, 'nik', 'nik');
}
In your students table, you should define a new column with name 'account_id' to represent the student account, and it should be nullable.
$table->unsignedBigInteger('account_id')->nullable();
$table->foreign('account_id')->references('nik')->on('accounts');
then , you can use it in your relation:
// Student Model
public function account()
{
return $this->hasOne(Account::class, 'account_id', 'nik');
}
// Account Model
public function student()
{
return $this->belongsTo(Student::class, 'account_id', 'nik');
}
You should not have one field (nik) repeated in two tables that's against database normalization. You should create student_id on Account table. That way you would be following Laravel's standard on One to One relationships.
// Student Model
public function account()
{
return $this->hasOne(Account::class);
}
// Account Model
public function student()
{
return $this->belongsTo(Student::class);
}

Loading values from many-to-many realtionship plus values from auto-generated table in Laravel

I am working on some kind of ambulance app and I need help on how to load relationship.
So, I have table appointment_statuses (and it is populated over the seeder because I need only 3 states - Done, In Progress, Not Performed), I have also the many-to-many relationship between the User model and Appointment model (appointment_user table which holds only IDs of both models) and now I am working on EMR system which means I can check all appointments that patient had in history.
Here is the image of the issue
So under "Status" I want to load name of that ID from appointment_statuses table instead to have only ID.
These tables have this structure:
Appointments
Status
These tables have these values:
Appointments table
Appointment statuses table
These are relations:
User:
public function role()
{
return $this->belongsTo(Role::class);
}
public function patient()
{
return $this->hasOne(Patient::class);
}
public function appointments()
{
return $this->belongsToMany(Appointment::class);
}
Appointment:
public function users()
{
return $this->belongsToMany(User::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
public function appointmentStatus()
{
return $this->belongsTo(AppointmentStatus::class);
}
Appointment_Statuses:
public function patient()
{
return $this->belongsTo(Patient::class);
}
public function appointment()
{
return $this->belongsTo(Appointment::class);
}
Here is a controller which is responsible for emr:
After I have added to controller this:
$user = User::with(['appointments', 'appointments.appointmentStatus'])->where('id', $id)->firstOrFail();
I get this in frontend:
{{ dd($user->toArray()) }}
SOLUTION TO THIS ISSUE
For anyone in future who gets this kind of issue just check the convention about the naming of the foreign keys. In my example, it was the issue, and if you are not sure that your foreign key name is correct then just in the model provide more information like this:
public function appointmentStatus()
{
return $this->belongsTo(AppointmentStatus::class,'appointment_statuses_id','id');
}
You can use nested relationship
$user=User::with(['appointments','appointments.appointmentStatus'])
->where('id',$id)
->first();
Also you have to modify relationship
public function appointmentStatus()
{
return $this->belongsTo(AppointmentStatus::class,'appointment_statuses_id','id');
}
For anyone in future who gets this kind of issue just check the convention about the naming of the foreign keys. In my example, it was the issue, and if you are not sure that your foreign key name is correct then just in the model provide more information like this:
public function appointmentStatus()
{
return $this->belongsTo(AppointmentStatus::class,'appointment_statuses_id','id');
}

Laravel defining relationship

Am still new to laravel
I have the following tables
user
id
first_name
last_name
educations
id,
user_id //references user id
type
Now in my user model i would like to get a specific users educations which can be many
so a user can have many educations but each education belongs to a single user.
So in my user model i have
public function education()
{
return $this->hasMany('App\ApplicantEducation','id','user_id');
}
In my Education model i have
public function user()
{
return $this->belongsTo('App\User','user_id','id');
}
But the above fails, I cannot retrieve user specific educations
Where am i going wrong?
try this:
in User Model:
public function educations()
{
return $this->hasMany('App\ApplicantEducation', 'user_id');
}
in Education Model:
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
Change return $this->hasMany('App\ApplicantEducation','id','user_id');
to return $this->hasMany('App\ApplicantEducation','user_id', 'id'); you also ommit the id and user_id.
As your foreign_key is well formed, you can also rwite this simple code,
class User{
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}
}
Class Educations{
public function user()
{
return $this->belongsTo('App\User');
}
}
Here,
$this->hasMany('App\ApplicantEducation','id','user_id');
In above statement first argument should be Model second should be foreign key and the third one is any other key from Education model.
Here, second and third arguments are not mandatory.
In User Model
class User...{
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}
In Education Model
public function user()
{
return $this->belongsTo('App\User');
}
Here, additional parameters are not mandatory might be your addition parameters creates issue,
and now you can retrieve your user with Education by
$user = User::with('education')->get();
This can retrieve all the users with their education.
I hope it helps,Thank you, Happy coding.
You should try this:
Education Model
public function user()
{
return $this->belongsTo('App\User','user_id);
}
User Model
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}

Laravel selection from pivot table

I have three tables: users, items and user_items. A user has many items and a item belongs to many users.
**Users**
id
username
password
**Items**
id
name
**User_items**
id
user_id
item_id
Models:
class User extends Eloquent {
public function items()
{
return $this->belongsToMany('Item', 'user_items', 'item_id', 'user_id');
}
}
class Item extends Eloquent {
public function users()
{
return $this->belongsToMany('User', 'user_items', 'user_id', 'item_id');
}
}
I need to select all items table, print it and highlight rows which belongs to specific user id=1.
Selection highlighted output:
What is the right way to do it (in laravel style)?
You can use it like this
public function user_items()
{
return $this->belongsToMany('User', 'user_items', 'user_id', 'item_id')->withPivot('id');
}
Like this you can access values of third table.
Some useful links-
http://www.developed.be/2013/08/30/laravel-4-pivot-table-example-attach-and-detach/
http://vegibit.com/many-to-many-relationships-in-laravel/
http://laravel.com/docs/4.2/eloquent
You can do it like this way...
class User extends Eloquent {
public function items()
{
return $this->belongsToMany('Item', 'user_items', 'item_id', 'user_id')->withPivot('id');
}
}
class Item extends Eloquent {
public function users()
{
return $this->belongsToMany('User', 'user_items', 'user_id', 'item_id')->withPivot('id');
}
}
From controller..
$user_id = 2;
Item::with(['users'=>function($q) use ($user_id){$q->where('user_id',$user_id);}])->get();
In view at the time of listing a row you can highlight the row just use a condition as each item->users is blank or not.

Laravel Pivot Table and indirect relationship

I'm writing a survey with Laravel 4 and need the ability for users to be able to take the same survey multiple times (and have their answers saved as different instances.)
I currently have a pivot table called survey_user that links a user to an invited survey. A potentially positive side effect of the pivot table is that its primary key could be used to have unique survey instances.
My problem is figuring out how to get answers, specifically through the user model. Answers table would contain a foreign key to the primary of the pivot table.
My User model:
class User extends Eloquent {
public function surveys() {
return $this->belongsToMany('Survey', 'survey_user')
->withPivot('id', 'completed_at');
}
public function answers() {
// This should return all of the user's answers, irrespective of
// survey id's.
}
}
Tables:
surveys: id
users: id
survey_user: id, survey_id, user_id, completed_at
answers: survey_user_id, answer_text, ...
How might I accomplish this psuedo-relationship or perhaps a better way to structure?
Use relationships! Here's how I would do it:
class User extends Eloquent {
public function surveys() {
return $this->belongsToMany('Survey');
}
public function answers() {
return $this->hasMany('Answer');
}
}
class Survey extends Eloquent {
public function surveys() {
return $this->belongsToMany('User');
}
public function answers() {
return $this->hasMany('Answer');
}
}
class Answer extends Eloquent {
public function survey() {
return $this->belongsTo('Survey');
}
public function user() {
return $this->belongsTo('User');
}
}

Categories