【问题标题】:Laravel inter-user messaging systemLaravel 用户间消息传递系统
【发布时间】:2017-05-23 16:54:33
【问题描述】:

我正在为我的应用程序开发一个消息系统,目前我有两个表:

1)messages表:

Schema::create('messages', function (Blueprint $table) {
    $table->increments('id');
    $table->text('subject');
    $table->integer('sender_id');
    $table->text('body');
    $table->timestamps('create_date');
    $table->integer('sent_to_id');
});

2)users表:

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

目前,我可以将消息及其主题存储到messages 表中。现在,我想选择要向其发送消息的用户的id。这样我就可以用它来创建对话。

有什么方法可以列出所有用户并选择我想向其发送消息的首选用户?或任何有消息传递技术的人来帮忙?

【问题讨论】:

  • @shalvah 为什么我的问题被忽略???
  • ",现在我想选择要发送消息的用户的 ID,以便我可以使用它来创建对话。有没有办法可以列出所有用户并选择首选用户我想发消息给?”这不是很清楚。你能具体解释一下你想做什么吗?
  • 我希望能够获取正在向其发送消息的用户的 id,以便我可以将其存储在我的消息表中..我将如何实现这一目标??跨度>
  • 你的 sender_idsent_to_id 应该是用户表上的外键,对于一个
  • 如果你用一个使用例子更新你的问题会很棒。

标签: php laravel laravel-5 eloquent relationships


【解决方案1】:

您的问题有点含糊,过于笼统。无论如何,我假设您想让用户向系统中的其他现有用户发送消息。

在我们开始之前,请注意其中涉及很多设计决策。我将简单地使用最简单和最快的方法,因为它只是一个让您入门的演示。

为了使用户能够相互发送消息,您需要在数据库迁移中设置外键,设置 eloquent 关系并创建要在控制器类中使用的辅助方法。

1。外键

非常不言自明;但如果您不知道我在说什么,请查看documentation on foreign key constraints

您的users 表迁移暂时不需要更改,所以我跳到messages 表迁移:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateMessagesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('messages', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('sender_id');
            $table->integer('sent_to_id');
            $table->text('body');
            $table->text('subject');

            // It's better to work with default timestamp names:
            $table->timestamps(); 

            // `sender_id` field referenced the `id` field of `users` table:
            $table->foreign('sender_id')
                  ->references('id')
                  ->on('users');

            // Let's add another foreign key on the same table,
            // but this time fot the `sent_to_id` field:
            $table->foreign('sent_to_id')
                  ->references('id')
                  ->on('users');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('messages');
    }
}

正如 cmets 解释的那样,这会在您的 messages 表上设置外键约束。不要忘记:php artisan migrate:refresh [-seed]

2。模型关系

首先,看看documentation on eloquent relationships。然后看看我们如何设置你的两个模型之间的关系; MessageUser

这是你的App\Message 课程:

<?php

namespace App;

use App\User;
use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    protected $fillable = ['body', 'subject', 'sent_to_id', 'sender_id'];

    // A message belongs to a sender
    public function sender()
    {
        return $this->belongsTo(User::class, 'sender_id');
    }

    // A message also belongs to a receiver    
    public function receiver()
    {
        return $this->belongsTo(User::class, 'sent_to_id');
    }
}

还有你的App\User 班级:

<?php

namespace App;

use App\Message;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    protected $fillable = ['name', 'email', 'password'];

    // A user can send a message
    public function sent()
    {
        return $this->hasMany(Message::class, 'sender_id');
    }

    // A user can also receive a message
    public function received()
    {
        return $this->hasMany(Message::class, 'sent_to_id');
    }
}

有了这些文件,您将拥有一个可靠的、雄辩的 API 供您使用。看看这些例子:

$user->sent       // All messages sent by this user
$user->received   // All messages received by this user

App\User::has('sent')->get() // Retrieve all users that have at lest one sent message
App\User::has('sent', '>', 2)->get() 

$user->sent()->where('subject', 'Happy new year!')->first();

有关更多示例,请参阅文档或在php artisan tinker 中与它们一起玩,看看它有多强大。

3。消息实现

现在您已准备好迁移和模型。您需要利用它们来实现您的用户间消息传递系统。

这需要很多样板代码,例如路由、控制器和视图,我不会在这里写出来。但我相信你能找到自己的出路。我只是在这里添加一个示例使用示例。

我假设您需要一个控制器才能让用户向另一个用户发送消息。这是一个例子:

<?php

namespace App\Http\Controllers;

use Auth;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ConversationController extends Controller
{
    public function sendMessage(Request $request)
    {
        // Do the validation...

        // Send the message from the current user to the user with ID of 1,
        // You probably always want the current logged-in user as the sender.
        // We talk about the recipient later...
        //
        Auth::user()->sent()->create([
            'body'       => $request->body,
            'subject'    => $request->subject,
            'sent_to_id' => 1,
        ]);   

        // Set flash message, render view, etc...
    }
}

这将从登录用户发送一条消息给 ID 为1 的用户。您的问题主要是关于收件人以及如何列出用户并从中选择。我们稍后再谈。

4。清理

这行得通,但它不是那么干净。让我们将逻辑包装在模型方法中:

class User extends Authenticatable
{
    // ...

    public function sendMessageTo($recipient, $message, $subject)
    {
        return $this->sent()->create([
            'body'       => $message,
            'subject'    => $subject,
            'sent_to_id' => $recipient,
        ]);   
    }
}

将此方法添加到您的 App\User 模型中,并让您的控制器代码如下:

Auth::user()->sendMessageTo(1, $request->subject, $request->body);

更好,对吧?

4。收件人

剩下的唯一问题是关于收件人 ID。您可能有一个用户用来撰写消息的表单。它可能有一个名为body 的文本区域和一个名为subject 的主题输入。您只需要另一个输入,以便用户也可以传递收件人用户的 ID。然后你就说:

Auth::user()->sendMessageTo($request->recipient, $request->subject, $request->body);

您可能希望使用列出用户姓名的下拉菜单(或自动完成小部件)。呈现表单时,您可以像这样将用户数据传递给视图:

<?php

namespace App\Http\Controllers;

use Auth;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ConversationController extends Controller
{
    public function composeMessage()
    {
        // ...

        // Get a collection of `[id => name]` probable recipients,
        // so that the logged-in user can choose from. Note that 
        // you probably want to exclude the current user herself
        // from the list.
        $users = User::where('id', '!=', Auth::id())->pluck('name', 'id');

        return view('view.name', compact('users'));
    }
}

然后,在您的视图中,您可以像这样呈现这些数据:

{{ Form::select('recipient', $users) }}
// See: https://laravelcollective.com/docs/5.3/html

很简单,对吧?这是未经测试的代码,但希望它能为您提供灵感。

毕竟,为什么不改用设计良好、测试良好的消息包呢?认识Laravel Messenger

【讨论】:

  • 我得到这个 在我的收件人输入字段中
  • 已修复。 composerMessage 方法中的查询行应该是这样的:$users = User::where('id', '!=', Auth::id())-&gt;pluck('name', 'id'); 好像lists() 不再可用了。你的确切 Laravel 版本是什么?
  • laravel 5.2.收件人输入字段仍然无法正常工作
  • 怎么不工作了?在渲染视图之前转储$users,让我们看看里面有什么。使用详细信息更新您的原始问题。它对我有用,see this
  • 我得到未定义的变量用户
猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
  • 2012-06-04
  • 2014-10-15
  • 1970-01-01
  • 2011-01-22
  • 2015-11-18
相关资源
最近更新 更多