User Follow/Subscription Relationship Model In Laravel - php

I am trying to create a youtube style subscription model for my application. I've had small amounts of success so far, that being that you can follow other users and it stores who is following who in the database. However I am having trouble retrieving the list of people the current user is following.
The database:
users table (id, first_name, last_name, email, password, token, timestamps)
subscriptions Table (id, user_id, subscriber_id, timestamps)
user model:
public function subscriptions()
{
return $this->belongsToMany('App\User', 'subscriptions', 'user_id',
'subscriber_id')->withTimestamps();
}
public function subscribers()
{
return $this->belongsToMany('App\User', 'subscriptions', 'subscriber_id',
'user_id')->withTimestamps();
}
I am using this code to retrieve all of the current users subscriptions (aka who they are following)
$subscriber = Auth::user()->id;
$user = User::find($subscriber);
$userids = $user->subscriptions->lists('user_id');
return $userids;
Now, this code is currently returning a null value. On further investigation this makes sense as the query that is being run is incorrect
SQL Query:
select `user_id` from `users` inner join `subscriptions` on `users`.`id` = `subscriptions`.`subscriber_id` where `subscriptions`.`user_id` = 14
My current set up is trying to look for the wrong thing.
If user 1 follows users 2, 3 and 4 then my code should return 2, 3 and 4.
Can somebody please help correct my relationship set up or the code that I am running? It should be looking for the user_id in the subscriptions table based on the current users subscriber_ID.

Laravel 5.3 Eloquent Relationships
If you check the code at the end of the Many-to-Many relationships part, you will see this line of code.
return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
Here, we have the 'role_user' as the pivot (relationship) table, 'user_id' which is the foreign key in relationship table and primary key in user model, and 'role_id' is foreign key in relationship table and primary key in roles model.
So when you try to do this:
public function subscriptions()
{
return $this->belongsToMany('App\User', 'subscriptions', 'user_id',
'subscriber_id')->withTimestamps();
}
You are actually taking 'subscriber_id' as a foreign key in your relationship table and primary key for a subscriber. Since the function is trying to get the subscriptions, reaching to the subscriber id's won't do the work. This is why when you changed them they worked.
The result should look like this:
public function subscribers()
{
return $this->belongsToMany('App\User', 'subscriptions', 'user_id',
'subscriber_id')->withTimestamps();
}
public function subscriptions()
{
return $this->belongsToMany('App\User', 'subscriptions', 'subscriber_id',
'user_id')->withTimestamps();
}

So out of pure chance, I swapped the subscribers() and subscriptions() relationships about and it's now returning the correct data.. I don't understand why but it is definitely returning the ID's that I was expecting.
I'll keep the question open for now in case anyone with a clear solution answers.

Related

Laravel 8 has many problems pulling data in the use of the associated table

I am developing a project. I have made associations using many variants, but I cannot pull the data. Can you help me?
user table: id, first_name, last_name, email, password, image, adress
user_teammates table: id, user_id(foreign user table id) , teammate_id (foreign user table id)
User Model
public function team()
{
return $this->belongsToMany(User::class, 'user_teammate', 'teammate_id','user_id');
}
UserTeammate Model
public function users_relate()
{
return $this->belongsToMany(User::class, 'user_teammates', 'user_id','teammate_id');
}
User Controller
public function index()
{
$teams = UserTeammate::find(Auth::id())->users_relate()->get();
return view('user.user')->with('teams', $teams);
}
Output
Error
Call to a member function users_relate() on null
Remember_token, created_at, updated_at fields were missing in the users I created over Seeder and when they created records on the site. When I filled them in, my problem was solved.

Many to Many Relation with custom pivot table

I have 4 tables in project's database:
users (id, name)
teams (id, name)
team_members (id, user_id, team_id)
team_member_permissions (team_member_id, team_id)
I need to get user's teams. My current solution is to create teamMembers relationship in User model:
public function teamMembers()
{
return $this->hasMany(TeamMember::class);
}
members relationship in Team model:
public function members()
{
return $this->hasMany(TeamMember::class);
}
permissions relationship in TeamMember model:
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
But how can I optimise it? For example, to get all teams for users I need to use
Team::whereHas('teamMember', function($query) use ($user){
$query->where('user_id', $user->id);
})->paginate();
But how can I implement a relationship that will contains all user's teams to get user's teams in one string of code, like $user->teams?
I suggest you use many to many relation in regards to your team_members tables to explicitly mention as pivot.
User model:
public function teams()
{
return $this->belongsToMany(Team::class, 'team_members');
}
Team model:
public function users()
{
return $this->belongsToMany(User::class, 'team_members');
}
Since you want to use whereHas clause on teamMember table, I believe that you want to extract teams based on the fact that all teams belonging to that user based on team_members table.
So, You can specify the table name on many to many relation as above.
Now you can use
$user->teams

How in Laravel make 2 relations to same table?

Having some troubles with relations in Laravel not sure is there any solutions but hope you guys help me.
So let's suppose I have 2 tables USERS and TRAINEES. USERS can be considered as company, admin, instructors depends on field role.
About relations USER as company can have many TRAINEES but also as instructors can have many TRAINEES. So in this case how can I build relations between them? table TRAINEES should have fields COMPANY_ID and INSTRUCTOR_ID ? or how? But it's same table USERS. I don't know if it's clear for you. Just ask me. Count on you guys
Design the users and trainees tables as follows:
users table columns/fields:
id (primary key)
username (string)
role (string, index)
trainees table columns/fields:
id (primary key)
name (string)
trainer_id (integer, index)
company_id (integer, index)
Then in your Trainees model, do this:
public function trainer()
{
return $this->belongsTo('App\User', 'trainer_id');
}
public function company()
{
return $this->belongsTo('App\User', 'company_id');
}
In your User model, do this:
public function trainees()
{
if($this->attributes["role"] == "company")
return $this->companyTrainees();
if($this->attributes["role"] == "instructor")
return $this->instructorTrainees();
return array();
}
public function companyTrainees()
{
return $this->hasMany('App\Trainee', 'trainer_id');
}
public function instructorTrainees()
{
return $this->hasMany('App\Trainee', 'company_id');
}
Use these relationships in your controllers and other places. This is not tested, but it should not be too buggy. Don't forget to seed the database with valid data, especially for the ids.

Laravel hasManyThrough 2 tables

i have two tables as below:
users table:
|id|name|email|password|created_at|updated_at
messages table:
|id|sender_id|receiver_id|message|created_at|updated_at
User model:
public function threads()
{
return $this->hasManyThrough(Message::class, User::class,'id','sender_id');
}
i'm trying retrieve message threads
which isn't working. any help appreciated.
This is an example from laravel eloquent relationship
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(
'App\Post',
'App\User',
'country_id', // Foreign key on users table...
'user_id', // Foreign key on posts table...
'id', // Local key on countries table...
'id' // Local key on users table...
);
}
}
can you review your code
It seems that you want to retrieve all messages that belongs to a single thread (list of users) using hasMany relationship Through User model, to do that You have to define hasManyThrough inside Thread model not in User model, here is an example:
User:
|id|name|email|password|created_at|updated_at|thread_id
Note thread_id foreign key because thread is a list of users
Thread:
class Thread extends Model {
public function messages() {
return $this->hasManyThrough(Message::class, User::class,'thread_id','sender_id', 'id', 'id');
}
}
Example from laravel doc

Laravel foreign key relation

I've got a strange problem.
I've a users table and a company table. A User belongsTo a company and a company hasMany users.
Both primary keys of the table are id.
In the laravel documentation I read the following:
Additionally, Eloquent assumes that the foreign key should have a
value matching the id column of the parent.
I've got this in my CompanyModel:
protected $table = 'company';
public function users()
{
return $this->hasMany(UserModel::class);
}
When I try this:
$users = CompanyModel::find(1)->users;
dd($users);
It's not working. When I add a foreign key in my relation it works!?:
protected $table = 'company';
public function users()
{
return $this->hasMany(UserModel::class, 'id');
}
This is strange right? What on earth am I doing wrong.
--EDIT--
In my users table I've got a company_id column!
Firstly, I would suggest you rename your Model from CompanyModelto Company and from UserModel to User.
Then ensure you have company_id in your users table. And in your users migration file connect the users table with the companies table as such:
$table->integer('company_id')->unsigned();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
Don't forget to refresh your database.
Then in your models, define the relationships as such:
// User model
// Laravel will automatically identify and use the `company_id` field in your reference
public function company(){
return $this->belongsTo(Company::class);
}
// Company model
public function users(){
return $this->hasMany(User::class);
}
You can then fetch your records in your controller as such:
$user = User::find(1);
$user_company = $user->company; // This might not be necessary in your controller, you can do it in your view
dd($users, $user_company);

Categories