我不太确定我是否理解 Laravel 中的 associate 方法。我理解这个想法,但我似乎无法让它发挥作用。
使用这个(精炼的)代码:
class User
{
public function customer()
{
return $this->hasOne('Customer');
}
}
class Customer
{
public function user()
{
return $this->belongsTo('User');
}
}
$user = new User($data);
$customer = new Customer($customerData);
$user->customer()->associate($customer);
当我尝试运行此程序时,我得到一个
Call to undefined method Illuminate\Database\Query\Builder::associate()
。
据我所知,我完全按照文档中的说明进行操作。
我做错了什么?
我必须承认,当我第一次开始使用 Laravel 时,我必须不断参考文档来了解其中的关系,即使在某些情况下我也没有完全理解它。
为了帮助您,
associate()
用于更新 belongsTo()
关系。查看您的代码,从 $user->customer()
返回的类是 hasOne
关系类,并且不会有关联方法。
如果你反过来做的话。
$user = new User($data);
$customer = new Customer($customerData);
$customer->user()->associate($user);
$customer->save();
它会起作用,因为
$customer->user()
是 belongsTo
关系。
要以相反的方式执行此操作,您将首先保存用户模型,然后将客户模型保存到其中,如下所示:
$user = new User($data);
$user->save();
$customer = new Customer($customerData);
$user->customer()->save($customer);
编辑:可能没有必要先保存用户模型,但我总是这样做,不知道为什么。
据我了解,
->associate()
只能在BelongsTo关系上调用。因此,在您的示例中,您可以做$customer->user()->associate($user)
。但是,为了“关联”Has* 关系,您使用 ->save()
,因此您的代码应该是 $user->customer()->save($customer)
只需在末尾添加
->save()
即可。
$user->customer()->associate($customer)->save();
为了使这些伟大的答案变得更好,我将添加更多关键点。
子模型而不是父模型上使用
associate/dissociate
associate
和 dissociate
在这里设置和取消设置模型/表关系的外键associate
或 dissociate
之后,我们需要调用 ->save()
方法将其存储到数据库中。hasOne
、hasMany
、belongsTo
默认创建如下外键:yourmodelname
+_id
。如果您想要不同的外键,请将其指定为这些方法的第二个参数。belongsTo
定义了由hasOne
/hasMany
方法定义的反向关系资源:
david-barker的回答的一点评论
“可能没有必要先保存用户模型,但我总是这样做,不知道为什么。”
$user = new User($data);
(它只在内存中创建一个对象 - 而不是在数据库中)
$user->save();
$user = User::create($data);
- 这一步即可创建并保存用户
$user
对象后,您才能访问
$user->id
、
$user->created_at
、
$user->updated_at
属性。
| Field Name | Field Type |
|-------------|------------|
| id | integer |
| name | string |
| email | string |
| password | string |
| created_at | timestamp |
| updated_at | timestamp |
用户型号:
// your namespaces...
class User extends Model
{
// Define the one-to-many relationship (a user has many addresses)
public function addresses()
{
return $this->hasMany(Address::class);
}
// Prescoped query to get the default address
public function defaultAddress()
{
return $this->hasOne(Address::class)->where('is_default', true);
}
}
地址(子表)
| Field Name | Field Type |
|-------------|-------------|
| id | integer |
| user_id | integer | -- Foreign key to link to users
| address | string |
| city | string |
| postcode | string |
| is_default | boolean | -- Flag for marking the default address
| created_at | timestamp |
| updated_at | timestamp |
地址型号:
// your namespaces...
class Address extends Model
{
// Define the inverse of the relationship (an address belongs to a user)
public function user()
{
return $this->belongsTo(User::class);
}
}
沙盒根据belongsTo方法设置子模型的外键(如果需要,可以采用自定义外键)此外,我们使用
user()
来获取预设范围的查询构建器,而不是相关的用户记录。我们如何使用
associate
:
// Find the user where id=1
$user = User::where('id', 1);
// Find the address by postcode
$address = Address::where('postcode', 'EH67DN')->first();
// 'user_id' is set (this only happens in memory, not saved yet)
$address->user()->associate($user);
$address->is_default = 1; // makring this as a default user's address
// user_id is taken by default, unless you specify a different one in your user model
$address->save();
分离(只能用于儿童)通过将子模型上的外键(例如,我们如何使用
user_id
)设置为null
来删除关系。
dissociate
:
// Find the address
$address = Address::where('user_id', 1);
$address->user()->dissociate(); // set user_id to null
$address->is_default = null;
// Save the change in the database (user_id is now null)
$address->save();
associate()
方法 - 在子模型
上设置外键(例如,
user_id
)。具体来说,它从父模型(例如,User)获取主键(id),并将其分配给子模型(例如,Customer)上的外键字段(
user_id
)。
dissociate()
方法 - 通过将子模型上的外键(例如,
user_id
)设置为
null
来删除关系。