简体   繁体   English

雄辩的1:n关系查询

[英]Eloquent querying 1:n relationship

I have 2 tables in my database, a notifications table and a notifications_user table. 我的数据库中有2个表,一个notifications表和一个notifications_user表。

A notification can have many notification users. 一个通知可以有许多通知用户。 And a result in my notification model I have the following relationship, 结果,在我的通知模型中,我有以下关系,

public function user()
{
    return $this->belongsToMany('User')->withPivot('is_read');
}

What I am wanting to achieve is to get all notifications that are unread (or is_read = 0), the is_read column is in the notification user table though and I cannot work out how to run a query on it becuase of that. 我想要实现的是获取所有未读的通知(或is_read = 0),尽管is_read列位于通知用户表中,但由于这一点,我无法解决如何对其执行查询的问题。

Current I have this, 目前我有这个

$unread = Notification::has('user')->with('user')->get();

Now this pulls the relationship into the results, but takes no account of the is_read value. 现在,这会将关系拉入结果,但不考虑is_read值。

Is there a way to select all the data from a table based on a value in its 1:n relationship. 有没有一种方法可以根据表中1:n关系中的值从表中选择所有数据。

You can query on the relationship by doing something like: 您可以通过以下方式查询关系:

$unread = Notification::has('user')->with('user')->where('is_read','!=', 0)->get();

Check the docs: http://laravel.com/docs/5.1/eloquent-relationships#querying-relations 检查文档: http : //laravel.com/docs/5.1/eloquent-relationships#querying-relations

So while it may make sense to have the relation that notifications have many users it really doesn't make sense from an ownership. 因此,尽管具有通知具有许多用户的关系可能是有意义的,但从所有权的角度来看,这实际上是没有意义的。 Notifications are one-time things while users persist in a way. 通知是一次性的事情,而用户以某种方式坚持下来。 So try to think of users as the base object and notifications as the abundant resource. 因此,尝试将用户视为基础对象,将通知视为丰富的资源。

The goal here is to get the users notifications so out of this you have to choose whether to duplicate notifications for each user or have one notification for many users. 此处的目标是获取用户通知,因此您必须选择是为每个用户复制通知还是为多个用户创建一个通知。 In one case where it's universal notifications (admin panel maybe) and the other is notifications that are personal to the user. 在一种情况下,它是通用通知(可能是管理面板),另一种情况是用户个人的通知。 If you're doing the latter you don't really need a pivot table and just a notifications table. 如果要进行后者,则实际上并不需要透视表,而只需要一个通知表。

User -> hasOne -> Notification

Notification -> belongsTo -> User

This enables you to really customize the notifications per-user than relying on maybe another table for read notifications you can just mark it as "read" in the row. 这样一来,您可以真正针对每个用户自定义通知,而不必依赖于另一个表来读取通知,您只需在行中将其标记为“已读”即可。

If however you need universal notifications the structure just implements a third table called a pivot as you know. 但是,如果您需要通用通知,则该结构将实现一个称为枢轴的第三张表。 (I noticed you have the class names pluralized which is not recommended) (我注意到您有不建议使用的类名复数形式)

User -> Notification_User -> Notification

For ease you also could just soft-delete the notification_user row or notification themselves. 为了简便起见,您也可以只删除Notification_user行或通知本身。 You can simply just say ->withTrashed()->limit(x) to get previous notifications. 您只需说出-> withTrashed()-> limit(x)即可获得先前的通知。

This really simplifies the work done by the DB and your code. 这确实简化了数据库和您的代码所做的工作。 The personal notifications allows you to order by creation/update and deal with read in two ways, soft-deletion and IsRead variables. 个人通知允许您通过创建/更新进行排序,并以两种方式处理读取,即软删除和IsRead变量。

Your code becomes as simple as this. 您的代码就这样简单。

Auth::user()->notifications()

Your User class has the following (assuming standard naming schemes) 您的User类具有以下内容(假设使用标准命名方案)

public function notifications()
{
    //You're free to append other requirements here
    return $this->hasMany('App\Notification','id','user_id');
}

The Notification class has the inverse 通知类具有反函数

public function user()
{
    //You're free to append other requirements here
    return $this->belongsTo('App\User','user_id','id');
}

If for some reason you require to know all unread notifications universally just query the Notification table. 如果由于某种原因您需要普遍了解所有未读的通知,只需查询“通知”表即可。

Notification::where('isRead','null')->get();

Alternatively you can lazy load the users for each notification or group by users in this case for whatever purpose you need. 另外,在这种情况下,您可以出于所需的任何目的而按用户延迟加载每个通知或组的用户。

If this helped you to your solution could you mark it as the answer? 如果这对您的解决方案有所帮助,您可以将其标记为答案吗?

You can use the wherePivot and orWherePivot functions provided by laravel for relations. 您可以使用wherePivot提供的wherePivotorWherePivot函数来建立关系。 Link 链接

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

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