简体   繁体   中英

Laravel Eloquent relationships and connecting multiple tables

I am trying to build a messaging system for a job site using Laravel 5 and using the Eloquent ORM. The basic premise is that someone posts up a job, and people can respond to that job via a message. The MySQL database is structured as so:

**users table**
id
username
password

**jobs table**
id
user_id (FK with id on Users table)
slug
title
description

**conversations table**
id
job_id (FK with id on Jobs table)

**messages table**
id
conversation_id (FK with conversations table)
user_id (FK with id on users table)
message
last_read

**conversation_user table**
conversation_id (FK with id on Conversation table)
user_id (FK with id on Users table)

When a user finds a job they like, they can send a message to the job creator which will in turn create a new conversation. The newly created conversation id is then used passed to the messages table (alongside the message text itself) and then the conversation_user pivot table is updated with the conversation id as well as the two users who are participating in the conversation (ie the person who posted the job and the person sending the message)

I have a model for each table and a summary of the relationships are:

**Job.php**
HasMany - Conversation model
BelongsTo - User model

**Conversation.php**
BelongsTo - Job model
HasMany - Message model
BelongsToMany - User model

**Message.php**
BelongsTo - Conversation model
BelongsTo - User model

**User.php**
HasMany - Job model
HasMany - Message model
BelongsToMany - Conversation model

I have setup a query scope in Conversation.php (my Eloquent model for the Conversations table) which accomplishes the task of displaying the conversations that the authenticated user is participating in:

public function scopeParticipatingIn($query, $id)
{
    return $query->join('conversation_user', 'conversations.id', '=', 'conversation_user.conversation_id')
        ->where('conversation_user.user_id', $id)
        ->where('conversation_user.deleted_at', null)
        ->select('conversations.*')
        ->latest('updated_at');
}

and via my Conversations Repository, I pass on the results of the query scope to my view in my MessagesController like so:

public function __construct(ConversationInterface $conversation)
{
    $this->middleware('auth');
    $this->conversation = $conversation;
}

public function index()
{
    $currentUser = Auth::id();

    $usersConversations = $this->conversation->ParticipatingIn($currentUser, 10);

    return view('messages.index')->with([
        'usersConversations' => $usersConversations
    ]);
}

and for reference the ConversationInterface is bounded to my ConversationsRepo:

public $conversation;
private $message;

function __construct(Model $conversation, MessageInterface $message)
{
    $this->conversation = $conversation;
    $this->message      = $message;
}

public function participatingIn($id, $paginate)
{
    return $this->conversation->ParticipatingIn($id)->paginate($paginate);
}

My question is, given I have what I believe are the right relationships, how I can pass the title of the specific job from the job_id on the conversations table and also the first few words of the last message that was sent within the conversation?

I'm sorry if I'm stating the obvious, but:

Conversation model belongs to Job Model. As you already has the conversation object/id, just do this:

//Controller
$conversation = App\Conversation::find($id);
return view('your view', compact('conversation'));

//View
$conversation->job->title; //the conversation belongs to a job, so requesting the job will return an instance of the job model, which can be asked for the title.

You can also use this on the view to get the first chars from the message:

substr($conversation->messages->last()->message,0,desired lenght);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM