简体   繁体   English

如何在 Laravel Eloquent 中构建具有多级关系的查询

[英]How to build query with multi level relations in Laravel Eloquent

I have three models.我有三个模型。 Sponsor , Optin and Participant . SponsorOptinParticipant Sponsor has a one-to-many relationship with Optin and Optin has a one-to-one Participant . SponsorOptin具有一对多的关系, Optin具有一对一的Participant

Which make the models look like this:这使模型看起来像这样:

Sponsor model赞助商model

class Sponsor extends Model
{ 
    public function optins()
    {
        return $this->hasMany(Optin::class);
    }
}

Optin model可选 model

class Optin extends Model
{    

    public function sponsor()
    {
        return $this->belongsTo(Sponsor::class);
    }
    public function participant()
    {
        return $this->belongsTo(Participant::class);
    }
}

Participant model参与者 model

class Participant extends Model
{
    public function optins()
    {
        return $this->hasMany(Optin::class);
    }

    public function scopeCreatedToday($query)
    {
        return $query->whereDate('created_at', Carbon::today());
    } 
}

Now in a daily scheduled task I want to iterate through all participants that where created today and that opted in to a certain Sponsor to send them like an email or something.现在,在每日计划任务中,我想遍历今天创建并选择加入某个赞助商的所有参与者,例如 email 或其他东西。 Now I got as far as echoing the id's of the belonging participants.现在,我尽可能地回应了所属参与者的身份。 But the next step is to get the participant object and filter them by the right created date.但下一步是获取参与者 object 并按正确的创建日期过滤它们。 But I am a little lost on how to handle this.但我对如何处理这个问题有点迷茫。

$sponsor = Sponsor::find(1);
$count = $sponsor->optins()->count();
echo("Count: " . $count . "\n");
$optins = $sponsor->optins()->get();
foreach($optins as $optin)
{
    echo($optin->participant_id . "\n");
}

EDIT: After rethinking the structure I figured out that Optin has a many-to-one relation with Participant .编辑:重新考虑结构后,我发现OptinParticipant具有多对一的关系。

Step 1 is to define the relationship between Sponsor and Participant models using a belongsToMany relationship.第 1 步是定义SponsorParticipant模型之间的关系,使用belongsToMany关系。 I assume your optins table has both participant_id and sponsor_id columns.我假设您的optins表同时具有participant_id ID 和sponsor_id列。

class Sponsor extends Model
{ 
    public function optins()
    {
        return $this->hasMany(Optin::class);
    }
    public function participants()
    {
        return $this->belongsToMany(Participant::class, 'optins');
    }
}

Then you want to eager load the relationship using the with() method, and also filter it based on your condition of the creation date.然后,您想使用with()方法预先加载关系,并根据您的创建日期条件对其进行过滤。 This will make the participants available as a collection.这将使参与者可以作为一个集合使用。

$date = now()->subDay(); // or whatever you like.
$start = $date->startOfDay();
$end = $date->endOfDay();

$sponsor = Sponsor::where('id', 1)
    ->with([
        'participants' => function($q) use ($start, $end) {
            $q->whereBetween('created_at', [$start, $end]);
        }
    ]);

$count = $sponsor->participants->count();
echo("Count: $count\n");
foreach($sponsor->participants as $participant)
{
    echo("$participant->name\n");
}

Since Participant has a one-to-many relation with Optin I added the following relation on the Sponsor model.由于ParticipantOptin具有一对多关系,我在Sponsor model 上添加了以下关系。 With the passing the Optin model als a second parameter to the belongsToMany method, since it functions as an intermediate table.随着Optin model 的传递,它也是belongsToMany方法的第二个参数,因为它充当中间表。

public function participants()
{
    return $this->belongsToMany(Participant::class, Optin::class);
}

From there out I could easily get all the participants with adding subqueries belonging to the sponsor like so:从那里开始,我可以通过添加属于赞助商的子查询轻松获得所有参与者,如下所示:

$sponsor = Sponsor::find(1); 
$participants = $sponsor->participants()->createdToday()->get();
foreach($participants as $participant)
{
    //do something with $participant
}

if you want multi level data from same table this solution help you with hasmany relationship in laravel.and with('point') is function name.your name will be diferent.如果您想要来自同一个表的多级数据,此解决方案可以帮助您处理 laravel 中的许多关系。with('point') is function name.your name will be different.

class Master extends Model
{
    public function point() {
        return $this->hasMany(Master::class,'point_id')->with('point');
    }
}

please try to define the primary key's of all models and when use the function's set the foreign keys of every function请尝试定义所有型号的主键,使用该功能时设置每个function的外键

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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