Laravel One to Many relation with 2 primary keys - laravel

I've 2 tables
Users table
id
name
...
Chats table
id
from_id // fk - id on users, the user sent the message
to_id // fk - id on users, intended user
message_body
Now, I'm trying to set up One to Many relation where user has many chat messages but a chat message has two user. from and to user
How can I define this relationship?. I have to user eager loading.
I tried to use Compoships but it didn't work.
My code
User Model
public function chats() {
return $this->hasMany(Chat::class, ['from_id', 'to_id'], 'id');
}
Chat Model
public function user() {
return $this->belongsTo(User::class, ['from_id', 'to_id'], 'id');
}

public function chats() {
return $this->hasMany(Chat::class, 'from_id', 'id') + $this->hasMany(Chat::class,'to_id','id');
}
public function userFrom() {
return $this->belongsTo(User::class, 'from_id', 'id');
}
public function userTo() {
return $this->belongsTo(User::class, 'to_id', 'id');
}

Why don't you do something like that?
On your User model, set up two relationships like this:
public function chatsFrom() {
return $this->hasMany('App\Chat', 'from_id');
}
public function chatsTo() {
return $this->hasMany('App\Chat', 'to_id');
}
Then, on your Chat model, also set up two relationships, one to from and another to to, both referencing a User model. Like this:
public function fromUser() {
return $this->belongsTo('App\User', 'from_id');
}
public function toUser() {
return $this->belongsTo('App\User', 'to_id');
}
This way, you can access the relationships using something like this:
$user->chatsFrom();
$user->chatsTo();
$chat->fromUser();
$chat->toUser();

Related

Laravel HasMany relation with parameters

i have a relation between User model and Friend model
User.php
public function friends()
{
return $this->hasMany(Friend::class);
}
the relation actually returns all the records where the foreign key column (user_id) between User and Friend equals the current user's id but i want to return also the records where current user's id is in another column in friends table which's name is friend_id, this is my try
public function friends()
{
return $this->hasMany(Friend::class,'user_id','friend_id');
}
it's actually not returning the correct records
I don't think there is a direct way to that but you could try making 2 relations and merge them into one relation
public function friends() {
return $this->hasMany(Friend::class);
}
public function additionalfriends() {
return $this->hasMany(Friend::class, 'friend_id');
}
public function allfreinds() {
return $this->friends->merge($this->additionalfriends);
}
another solution you might try is
public function friends()
{
return Friend::where(function($query) {
$query->where('user_id',$this->id)
->orWhere('friend_id',$this->id);
});
}

How to get users from a group, with a union between two relationships in laravel?

I want to recieve all users from a group.
The problem is in this group their are student users (with a pivot table) and normal users.
So i have to merge them together, but i still want to maintain all possibilities from eloquent.
I came to this:
dd($this->belongsToMany(User::class)->union($this->hasManyThrough(User::class,Student::class,'class_id','id','id','user_id'))->get());
But as result i get:
My database relationships
Users
- id
Group
- id
Students
- id
- user_id (fk to users)
- class_id (fk to groups)
User_Group
- user_id (fk to users)
- group_id (fk to groups)
User-model:
public function students()
{
return $this->hasMany(Student::class);
}
public function groups()
{
return $this->belongsToMany(Group::class);
}
Student-model
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function class()
{
return $this->belongsTo(Group::class, 'class_id');
}
Group-model
public function students()
{
return $this->hasMany(Student::class, 'class_id');
}
public function users()
{
return $this->belongsToMany(User::class);
}
public function members()
{
//this causes the problem!!
return $this->belongsToMany(User::class)->union($this->hasManyThrough(User::class,Student::class,'class_id','id','id','user_id'));
}
in User model relationship
public function group(){
return $this->belongsToMany(Group::class);
}
in Group model relationship
public function user(){
return $this->belongsToMany(User::class, 'user_group');
}
in Students model relationship
public function user(){
return $this->belongsToMany(User::class, 'user_id', 'id');
}
public function group(){
return $this->belongsToMany(Group::class, 'class_id', 'id');
}
you can call now
$users = User::whereHas('groups',function ($query){
$query->where('group_id',1);
})->get();
Sometimes you have two relations from one model to another, due pivot tables. In my example you could go from users to groups with the relation user_groups and the relation students. To get all users that belong to a certain group i need to call both relations. To solve this issue, i made use of Abdulmajeed's example to solve it. You can see the code below. Thanks for helping me out.
public function members()
{
return User::whereHas('groups', function($q)
{
$q->where('id',$this->id);
})->orWhereHas('students', function($q)
{
$q->where('class_id',$this->id);
});
}

Laravel - Defining has-many-through relationship

I'm having a problem while creating a Forum with Laravel 5.7
I want to have these three models: User, Category, Thread and Post. The problem is that i don't how to define one of my Thread model relationships.
This model has a creator:
public function creator()
{
return $this->belongsTo('App\User');
}
...it has a series of replies:
public function replies()
{
return $this->hasMany('App\Post');
}
...and, finally, participants:
public function participants()
{
return $this->hasManyThrough('App\User', '???')
}
I should get the thread participants through its replies but it don't know if i should put the post class like this:
public function participants()
{
return $this->hasManyThrough('App\User', 'App\Post')
}
...or if this is an special case with some considerations. Any help?
Since posts acts as a pivot table, a BelongsToMany relationship is the better choice here:
public function participants()
{
return $this->belongsToMany('App\User', 'posts');
}

Updated: Why relationship works when user is Admin, but won`t when Regular user?

I have 3 models: User, Role and Currency. I am confused about relationship between them.
Then User is Admin this works:
Auth::user()->currency->symbol)
When regular User I get error:
Trying to get property of non-object
if dd(Auth::user()) it show user, but cant access to relationship with model Currency. Why it is so?
User model relationship:
public function currency()
{
return $this->belongsTo(Currency::class, 'currency_id');
}
Currency model relationship:
public function created_by()
{
return $this->belongsTo(User::class, 'created_by_id');
}
If you need extra information, let me know.
User model
public function currency()
{
return $this->belongsTo(Currency::class);
}
Currency model
public function users()
{
return $this->hasMany(User::class, 'created_by_id');
}
Going with an assumption that your User model has an attribute currency_id
$this->belongsTo(TABLE, FORIEGN KEY, TABLE KEY);
refer this
User model
public function currency()
{
return $this->belongsTo(Currency::class, 'currency_id', 'id');
}
Currency model
public function users()
{
return $this->hasMany(User::class, 'created_by_id', 'id');
}

Laravel HasManyThrough Keys

I have 3 models: User, Program, UserProgram. UserProgram is an actual model of its own.
Here are how the models look in the database:
users
id
programs
id
user_programs
user_id
program_id
I would like to have in my Program model:
function users() {
return $this->hasManyThrough('App\User','App\UserProgram');
}
But this does not work. How can I make this relationship work?
hasManyThrough is not used for this purpose. You need a many-to-many relationship.
class Users {
public function programs() {
return $this->belongsToMany('App\Program', 'user_programs', 'user_id', 'program_id');
}
}
and
class Program {
public function users() {
return return $this->belongsToMany('App\User', 'user_programs', 'program_id', 'user_id');
}
}

Resources