我有两个表之间的关系,连接表只有一个结果。
当我定义一个Laravel belongsToMany关系时,我不希望只返回一个只有一个元素的集合,而是让它单独返回该项。
有没有办法在Laravel模拟这个?
提前致谢。
[编辑]
我将尝试使用经典的用户/角色示例来解释我想要的内容。除了de users
和roles
表之外,我们还有一个users_roles
数据透视表,它将存储用户拥有的所有角色。用户可以在任何给定时间只有一个活动角色(由active
属性标识为true
)。
class User {
function role() {
return $this->belongsToMany('App\Role')->wherePivot('active', 'true');
}
}
通过这个关系定义,当我访问$user->role
时,我得到一个Roles的集合(只有一个元素)。我想要的是直接拥有该Role实例。
如果您只需要一个关系,我不知道为什么你有belongsToMany,但是下面的代码会帮助你:
public function products()
{
return $this->belongsToMany('App\Product');
}
public function specific_product()
{
return $this->products()
->where('column','value')->first();
}
要么
public function getSpecificProductAttribute()
{
return $this->products()
->where('column','value')->first();
}
我遇到了完全相同的问题,让我告诉你我是如何管理它的。
在我的情况下,材料和customer_types之间具有belongsToMany关系,数据透视表包含特定客户类型的材料价格,因此数据透视表中的记录(价格)与customer_types一样多。
我的期望:当为特定customer_type请求价格时,我希望将该特定customer_type的范围价格作为嵌套元素。
我得到了:只有1个元素的集合。
这就是我在模型开头的内容:
class Material extends Model
{
public function customer_types(){
return $this->belongsToMany('App\CustomerType', 'customertype_material', 'material_id', 'customertype_id')->withPivot('price');
}
}
当然,当我为特定customer_type请求customer_types时,结果不是预期的结果:
$resources = Material::with(['customer_types' => function($query) use ($customer_type_id){
$query->where('customertype_id', $customer_type_id);
}])->get();
它返回一个Material模型,其中包含一个带有1个元素的customer_types嵌套集合,迫使我使用first()或循环遍历1个元素。
解决方案:创建一个扩展数据透视表并为其添加关系的模型。
创建了一个扩展枢轴的新模型:
use Illuminate\Database\Eloquent\Relations\Pivot;
class CustomertypeMaterial extends Pivot
{
protected $table = 'customertype_material';
protected $fillable = ['price', 'customertype_id', 'material_id'];
}
现在,在我的材料模型中添加了一个指向这个新模型的关系:
public function scoped_price(){
return $this->belongsTo('App\CustomertypeMaterial', 'id','material_id');
}
最后查询加载这个新关系:
$resources = Material::with(['scoped_price' => function($query) use ($customer_type_id){
$query->where('customertype_id', $customer_type_id);
}])->get();
结果是一个Material模型,其中嵌套了scoped_price元素并由customer_type_id过滤
我不确定这是否是正确的方法,但它对我有用。
希望能帮助到你!