gileneusz
gileneusz

Reputation: 1485

Laravel getting users from multiple messages

I've got offers table with id's

Messages table with columns offer_id and from

and Users table with id's

I want to get users starting with offer $this in OfferResource My goal is to get users that have replied to the offer with at least one message.

I started to configure Offer model with function messages to get messages

public function messages(){
    return $this -> hasMany('App\Message');
}

so I'm able to get all messages (starting from offer resource):

'users' => $this->messages

How should I now configure messages model to get all users instead of messages?

I tried to write in Message model :

public function fromContact()
{
    return $this->hasOne(User::class, 'id', 'from');
}

and then:

'users' => $this->messages->fromContact

but i've got error: "message": "Property [fromContact] does not exist on this collection instance.",

How should I correct my code to make this work?

Upvotes: 1

Views: 202

Answers (3)

rkj
rkj

Reputation: 8287

Your messages table has from field that is referencing User model and offer_id field which referencing Offer model that means you have ManyToMany relations between Offer and User.

Offer Model

public function users(){
    return $this->belongsToMany(User::class, 'messages', 'offer_id', 'from')->using('App\Message');
}

Message Pivot

class Message extends Pivot {
     protected $table = 'messages';
}

User model

public function offers(){
    return $this->belongsToMany(Offer::class, 'messages', 'from', 'offer_id')->using('App\Message');
}

OfferResource

public function toArray($request)
{
    $users = $this->users; 

    return [
        'id' => $this->id,
        ... //add your offer fields here
        'users' => $users->toArray(), // here $users is a laravel Collection
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

Access from Controller or Route

Route::get('/offer', function () {
    return new OfferResource(Offer::with('users')->find(1)); //eager load users
});

Upvotes: 1

Adre Astrian
Adre Astrian

Reputation: 526

I am assuming the from field on the Messages table is populated using user ID. Then you could establish belongsToMany relationship between the Offer and User models. Since this is actually a many-to-many relation with a pivot table messages.

In the Offer model define

public function users()
{
    return $this->belongsToMany('App\User', 'messages', 'offer_id', 'from');
}

Then from the OfferResource you could load the offers data like this—

$offers = App\Offer::with('users')->get();

Then loop over the $offers like this:

foreach ($offers as $offer) {
    dd($offer->users); // one offer will have multiple users as a Collection
}

Similarly for an $offer of ID 1 you could do this

$offer = App\Offer::with('users')->find(1)

Then to get the users that commented on this offer just use $offer->users

See the official documentation for defining many-to-many relationship.

Upvotes: 1

Maraboc
Maraboc

Reputation: 11083

In the Message model you have to spesify the column that refer to the user :

public function fromContact()
{
    return $this->hasOne(User::class, 'from');
}

And then after geting the messages loop over them to get the user like this :

foreach ($this->messages as $message) {
    $user = $message->fromContact;
    // do somthing with the user :)
}

Upvotes: 1

Related Questions