我在两个表之间有一个关系,而一个联接表只有一个结果。
当我定义Laravel的归属关系时,我不希望只返回一个元素,而只返回一个元素。
有没有办法在Laravel中对此建模?
先谢谢了。
[ EDIT ]
我将使用经典的“用户/角色”示例来解释我想要的内容。除了de users
和roles
表之外,我们还有一个users_roles
数据透视表,该数据透视表将存储用户拥有的所有角色。用户在任何给定时间只能拥有一个活动角色(由active
属性为true
标识)。
class User {
function role() {
return $this->belongsToMany('App\Role')->wherePivot('active', 'true');
}
}
有了这个关系定义,当我访问$user->role
时,我将获得一组Roles(仅包含一个元素)。我想直接拥有那个Role实例。
答案 0 :(得分:2)
如果您只需要一种关系,我不知道您为什么拥有belongsToMany,但是下面的代码将为您提供帮助:
func employeeByFirstName(fName: String) -> [Employee]{
let viewContext = self.persistentContainer.viewContext
var substitutionVariables: [String: Any] = [String : Any]()
substitutionVariables["FIRSTNAME"] = fName
let fetchRequest = fetchRequestBy(name: "fetchByFirstName", variables: substitutionVariables) as! NSFetchRequest<Employee>
do {
let objects = try viewContext.fetch(fetchRequest)
return objects
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
func fetchRequestBy(name: String, variables: [String : Any]) -> NSFetchRequest<NSFetchRequestResult>? {
let model = self.persistentContainer.managedObjectModel
let fetchRequest = model.fetchRequestFromTemplate(withName: name, substitutionVariables: variables)
return fetchRequest
}
OR
public function products()
{
return $this->belongsToMany('App\Product');
}
public function specific_product()
{
return $this->products()
->where('column','value')->first();
}
答案 1 :(得分:0)
我面临着完全相同的问题,让我向您展示我是如何处理的。
在我的情况下,物料和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();
它返回的是一个带有customer_types嵌套集合且具有1个元素的Material模型,这迫使我使用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过滤
我不确定这是否是正确的方法,但是它对我有用。
希望有帮助!
答案 2 :(得分:0)
我遇到了这个问题,并且找到了一种非常干净的解决方法。
首先,更改返回belongsToMany
结果的访问器函数的名称,以反映这些函数返回多个结果的事实。在您的情况下,这意味着使用roles
而不是role
:
function roles() {
return $this->belongsToMany('App\Role')->wherePivot('active', 'true');
}
然后将以下内容添加到您的模型中:
protected $appends = ['role'];
public function getRoleAttribute() {
return $this->roles()->first();
}
现在,当您致电$user->role
时,您将获得第一项。
答案 3 :(得分:0)
就我而言,这是最直接的解决方案:
class User extends Model {
public function services()
{
return $this->belongsToMany(Service::class, 'service_user')
->using(ServiceUser::class)
->withPivot('user_id', 'service_id', 'is_main_service');
}
public function mainService()
{
return $this->hasOneThrough(Service::class, ServiceUser::class, 'user_id', 'id', 'id', 'service_id')
->where('is_main_service', 1);
}
}
数据透视表类:
use Illuminate\Database\Eloquent\Relations\Pivot;
class ServiceUser extends Pivot
{
}
答案 4 :(得分:-1)
拉威尔(Laravel)口才是魔幻原理。您可以覆盖魔术方法git lfs fetch --all
。如果没有属性,则调用__get
方法:
(在您的模型中)
__get
如果您的 public function __get ($name)
{
$answer = parent::__get($name);
if($name=='your_prop'){
$answer=!empty($answer)?$answer[0]:null;
}
return $answer;
}
对多关系返回任何东西,则以数组中的第一个为例。