如何使用雄辩的orm创建三向枢轴

nbewdwxp  于 2021-06-19  发布在  Mysql
关注(0)|答案(1)|浏览(326)

对拉雷维尔来说非常陌生,但我喜欢我目前所看到的。
我正在处理一个应用程序,其中客户参加会议和会议可以参加许多客户。除此之外,客户还可以在他们单独参加的会议上完成评估(即一个客户=一个评估)。同样值得指出的是,他们可能会或可能不会完成评估。
最好的解释是。。。

同样重要的是要指出数据必须是一致的-一个完整的评估必须在有客户在场的会议上完成。i、 e.客户必须出席会议-反之亦然-客户不可能完成他或她未出席的会议的评估。
这更多的是试图把我的头围绕着这个最好的结构,并使用在拉威尔雄辩的orm。我知道我可以找到一个有效的解决办法,这肯定会乱七八糟,但我宁愿知道正确的方法。
一些相关代码:

class Client extends Model
{
    public function sessions()
    {
        return $this->hasMany('App\Session');
    }

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

class Session extends Model
{
    public function clients()
    {
        return $this->hasMany('App\Client');
    }

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

//This is where I am having difficulty...

class Assessment extends Model
{
    public function client()
    {
        return $this->hasOne('App\Client');
    }

    public function session()
    {
        return $this->hasOne('App\Session');
    }
}

我面临的问题是,如何在“客户机”、“会话”和“评估”之间创建这种三方关系,从而强制执行完整性并提供访问。
我想了几件事:
创建一个“client\u session”透视表,并向其中添加一个名为“assessment\u id”的附加字段,并使用该字段将评估绑定到client和session的唯一组合。我不确定如何(甚至是否可能)定义与没有模型的表的这种关系。
使用“评估”作为数据透视表。我真的不喜欢这个想法,因为有可能不进行评估,但我仍然需要客户机和会话之间的关系,而将这种关系存储在“评估”中感觉是错误的。
创建一个单独的表“考勤”和相关的“数据透视类”,即扩展数据透视而不是模型-真的不确定这一个!
我已经设法使用简单的表来构造数据,并使用远离laravel的内部联接,但我想了解如何最好地用elowent实现这一点。
我还见过belongToMany()关系使用pivot(即扩展pivot而不是model)或hasmanythrough()关系。
我也看到了https://github.com/jarektkaczyk/eloquent-triple-pivot 但是这已经有4年没有维护了,所以我想这可以用任何有雄辩/拉威尔的船来完成。
任何帮助,非常感谢!

更新

好吧,@barghouthi对我的理解有很大帮助。目前我的模型如下所示:

class Client extends Model
{
    public function sessions()
    {
        return $this->belongsToMany('App\Session', 'attendance')->using('App\Attendance');
    }
}

class Session extends Model
{
    public function clients()
    {
        return $this->belongsToMany('App\Client', 'attendance')->using('App\Attendance');
    }
}

class Attendance extends Pivot
{
    public function client()
    {
        return $this->belongsTo('App\Client', 'attendance');
    }

    public function session()
    {
        return $this->belongsTo('App\Session', 'attendance');
    }

    public function assessment()
    {
        return $this->hasMany('App\Assessment','attendance');
    }
}

class Assessment extends Model
{
    public function attendance()
    {
        return $this->belongsTo('App\Attendance');
    }

    public function client()
    {
        // for now
        return $this->attendance()->client();
    }

    public function session()
    {
        // for now
        return $this->attendance()->session();
    }
}

我特意重命名了pivot表,以便反映pivot类。
我在考勤表中输入了一些虚拟数据:

当我在客户机会话中查询客户机id 1时,它将返回四个条目,而不是两个条目。就出勤表而言,4是正确的,但我只希望返回两个记录,即会议记录。

****更新

好吧-我学了很多东西,但还不太懂。这是我目前的解决方案:

class Client extends Model
{
    public function sessions()
    {
        return $this->belongsToMany('App\Session', 'attendance')->using('App\Attendance')->distinct('session_id');
    }

    public function assessments()
    {
        return $this->hasManyThrough('\App\Assessment', '\App\Attendance', 'client_id', 'id');
    }
}

class Session extends Model
{
    public function clients()
    {
        return $this->belongsToMany('App\Client', 'attendance')->using('App\Attendance')->distinct('client_id');
    }

    public function assessments()
    {
        return $this->hasManyThrough('\App\Assessment', '\App\Attendance', 'session_id', 'id');
    }
}

class Assessment extends Model
{   
    public function client()
    {
        return $this->belongsToMany('\App\Client', 'attendance', 'id', 'client_id')->using('\App\Attendance');
    }

    public function session()
    {
        return $this->belongsToMany('\App\Session', 'attendance', 'id', 'session_id')->using('\App\Attendance');
    }
}

考勤表只包含id、客户id和会话id。我认为不需要评估id,因为这是一对一的关系(即客户可以在特定会话中执行评估,也可以不执行评估)

class Attendance extends Pivot
{
    public function clients()
    {
        return $this->belongsTo('App\Client', 'attendance');
    }

    public function sessions()
    {
        return $this->belongsTo('App\Session', 'attendance');
    }

    public function assessments()
    {
        return $this->belongsTo('App\Assessment','attendance');
    }
}

这似乎在很大程度上起到了分开的作用。如果我试着打电话

$assessment->client->id

我得到以下结果:

Property [id] does not exist on this collection instance.

这意味着如果我想了解相关元素的属性,我在评估中的关系就不太正确。
当我使用

$assessment->client

输出为

[{"id":1,"created_at":"2018-10-24 19:15:41","updated_at":"2018-10-24 19:15:41","date_of_birth":"26 Sep 1974","gender":1,"initial_contact_date":"2013-05-01","initial_session_offered_date":"2002-07-06","contact_from":1,"presentation":"Vitae qui et nesciunt iste autem numquam earum. Illo repudiandae deleniti vel nesciunt non iure. Sunt est nemo ut excepturi illum temporibus.","counsellor_id":1,"pivot":{"id":1,"client_id":1}}]

所以我猜我很接近。

l2osamch

l2osamch1#

所以如果你有 client_session 或者 attendance 带的表格 id , client_id , session_id 您将此表用作评估表中的外键。
关键是数据透视表可以是一个模型
请参见多对多:定义自定义中间表模型

class Client extends Model
{
    public function sessions()
    {
        // using intermediate model
        return $this->belongsToMany('App\Session')->using('App\Attendance');
    }
}

class Session extends Model
{
    public function clients()
    {
        // using intermediate model
        return $this->belongsToMany('App\Session')->using('App\Attendance');
    }
}

class Attendance extends Pivot
{
    public function clients()
    {
        return $this->belongsTo('App\Client');
    }

    public function session()
    {
        return $this->belongsTo('App\Session');
    }

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

}

class Assessment extends Model
{
    public function attendance()
    {
        return $this->belongsTo('App\Attendance');
    }

    public function client()
    {
        // for now
        return $this->attendance()->client();
    }

    public function session()
    {
        // for now
        return $this->attendance()->client();
    }
}

因此,这样一来,没有出勤率就不能进行评估,出勤率可以有很多评估。
评估结果如下: id , attendance_id :指客户端和会话

相关问题