无法让 Laravel 同事工作

问题描述 投票:0回答:4

我不太确定我是否理解 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()

据我所知,我完全按照文档中的说明进行操作。

我做错了什么?

php laravel relational-database eloquent relationship
4个回答
53
投票

我必须承认,当我第一次开始使用 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);

编辑:可能没有必要先保存用户模型,但我总是这样做,不知道为什么。


10
投票

据我了解,

->associate()
只能在BelongsTo关系上调用。因此,在您的示例中,您可以
$customer->user()->associate($user)
。但是,为了“关联”Has* 关系,您使用
->save()
,因此您的代码应该是
$user->customer()->save($customer)


0
投票

只需在末尾添加

->save()
即可。

$user->customer()->associate($customer)->save();


0
投票

为了使这些伟大的答案变得更好,我将添加更多关键点。

  1. 正如所提到的,我们在
    子模型
    而不是父模型上使用associate/dissociate
  2. associate
    dissociate
    在这里设置和取消设置模型/表关系的外键
  3. 在调用
    associate
    dissociate
    之后,我们需要调用
    ->save()
    方法将其存储到数据库中。
  4. hasOne
    hasMany
    belongsTo
    默认创建如下外键:
    yourmodelname
    +
    _id
    。如果您想要不同的外键,请将其指定为这些方法的第二个参数。
  5. belongsTo
    定义了由
    hasOne
    /
    hasMany
    方法定义的反向关系

资源:

  1. 一对多(逆向)/属于
  2. belongsTo()的 github 构造函数

david-barker的回答的一点评论

“可能没有必要先保存用户模型,但我总是这样做,不知道为什么。”

    当我们这样做时
  1. $user = new User($data);
    (它只在内存中创建一个对象 - 而不是在数据库中)
  2. 为了保存这个对象,我们总是需要调用
  3. $user->save();
    
    
  4. 除非我们使用
  5. $user = User::create($data);
     - 这一步即可创建并保存用户
  6. 只有在保存了
  7. $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
     来删除关系。
© www.soinside.com 2019 - 2024. All rights reserved.