我正在探索Laravel的Eloquent,作为我项目当前本土的活跃记录数据层的替代品。目前,我有一个类User
,它支持与另一个类Group
的多对多关系。我目前的实现类似于:
class User {
protected $_groups; // An array of Group objects to which this User belongs
public function __construct($properties = []){
...
}
public function groups() {
if (isset($_groups))
return $_groups;
else
return $_groups = fetchGroups();
}
private function fetchGroups() {
// Lazily load the associated groups based on the `group_user` table
...
}
public function addGroup($group_id) {
// Check that the group exists and that this User isn't already a member of the group. If so, insert $group_id to $_groups.
...
}
public function removeGroup($group_id) {
// Check that the User is already a member of the group. If so, remove $group_id from $_groups.
...
}
public function fresh() {
// Reload user and group membership from the database into this object.
...
}
public function store() {
// Insert/update the user record in the `user` table, and insert/update/delete records in `group_user` based on the contents of `$_group_user`.
...
}
public function delete() {
// If it exists, delete the user record from the `user` table, and delete all associated records in `group_user`.
...
}
}
如你所见,我的班级:
User
与Group
的关系的内部表示,仅在调用store
时在数据库中进行更新; Group
存在且在创建新关联之前尚未与User
相关。如果有任何这些东西,Eloquent会自动为我照顾吗?或者,我的设计是否以某种方式存在缺陷,而Eloquent可以解决这个问题?
您可以假设我将User
重新实施为User extends Illuminate\Database\Eloquent\Model
并使用Eloquent belongsToMany
替代我当前的fetchGroups
方法。
答案 0 :(得分:3)
Eloquent在内部缓存关系结果,是的。您可以在Model::getRelationValue()
方法中看到这一点。
Eloquent还为您提供了帮助您manage the many-to-many relationship的方法。您可以在现有API中实现此功能。但是,这里有一些需要注意的事项:
使用attach()
,detach()
等时,会立即执行查询。调用父User::save()
方法只会保存用户的详细信息,而不会保存多对多关系信息。您可以通过暂时存储传递给API的ID来解决此问题,然后在致电User::store()
时对其进行操作。
使用附加/分离/等时不执行完整性检查。如果需要,可以在API中应用这些内容。
在多对多关系中添加或删除ID不会影响初始关系查询的缓存结果。您必须添加逻辑以将相关模型插入或移除到集合中。
例如,我们假设User
有两个Group
。加载用户时,我可以使用$user->groups
访问这些组。我现在在User模型中缓存了一组Groups。如果我再次呼叫$user->groups
,它将返回此缓存的Collection。
如果我使用$user->detach($groupId)
删除一个组,则会执行查询以更新连接表,但缓存的Collection不会更改。添加组也是如此。