Laravel Eloquent - 关系上的 firstOrCreate()

Posted

技术标签:

【中文标题】Laravel Eloquent - 关系上的 firstOrCreate()【英文标题】:Laravel Eloquent - firstOrCreate() on a relationship 【发布时间】:2014-07-20 20:44:04 【问题描述】:

当我在另一个模型的关系上尝试 firstOrCreate() 时,它不起作用:

Client::find($id)->users()->firstOrCreate(array('email' => $email));

这会返回一个错误提示

调用未定义的方法 Illuminate\Database\Query\Builder::firstOrCreate()

直接在模型User 上运行它会起作用。

【问题讨论】:

这行不通,您必须手动/直接使用 User 模型进行操作,因为 users() 应该在调用 get() 时返回一个集合对象,在这种情况下它将返回一个 @ 987654327@ 实例。 我用我自己的模型对此进行了测试,这很有效——你是如何定义你的关系的?您是否使用任何 belongsTo、hasOne、hasMany 关系,或者您是否使用 DB 类或类似的东西定义了自己的关系?或者您可能没有任何具有给定 ID 的客户? 如果您使用 laravel 关系,它也被记录在 laravel.com/docs/5.1/… 中,它应该可以工作。如果你这样做了,但它不起作用,我们需要更多的代码。 【参考方案1】:

这行不通,您必须手动/直接使用 User 模型来完成,因为 users() 应该返回一个集合对象

这是正确的,users() 函数不返回(新的、空的或创建的)用户模型,它返回一个集合对象。

如果您使用 laravel 关系,它也被记录在 http://laravel.com/docs/5.1/eloquent-relationships#inserting-related-models 中,它应该可以工作。

您误解了该文档。关系对象有一个 create() 方法和一个 save() 方法,但是关系对象不是一个完整的模型对象。要获得完整用户模型对象(例如 firstOrCreate())的所有功能,您必须在模型对象上调用它们。

因此,例如,这段代码应该可以工作:

$user = User::firstOrNew(array('email' => $email));
Client::find($id)->users()->save($user);

请注意,将 $user 对象直接从 Client 模型的关系中保存在这里应该是可以的,即使它可能已经存在这里,它也应该在您这样做时更新 $user 对象上的 client_id 字段。

【讨论】:

【参考方案2】:

应该这样做:

Client::find($id)->first()->users()->firstOrCreate(array('email' => $email));

【讨论】:

【参考方案3】:

你可以使用updateOrCreate:

$user = App\User::query()->firstWhere('email', 'radical@example.com');

$user->sandwiches()->updateOrCreate(['user_id' => $user->id], [
    'cabbage' => false,
    'bacon' => 9001,
]);

updateOrCreate 有两个参数。第一个是匹配条件。第二个是 upsert 数据。例如,如果没有user_id === $user->id 的行,则将使用该行和第二个参数中的字段创建一条记录。

【讨论】:

实际上,由于sandwiches已经是User模型上的关系,它已经匹配user_id;因此第一个参数['user_id' => $user->id]实际上可以保留为空数组[]【参考方案4】:

firstOrCreate 方法将尝试使用给定的列/值对来定位数据库记录。如果在数据库中找不到模型

public function firstOrCreate() 
    $requestData = [
        'name' => 'Salma Klocko',
        'email' => 'maida39@frami.biz'
    ];
    $customer = Customer::firstOrCreate($requestData);
    echo "Insert customer detail Successfully with ID : " . $customer->id;

【讨论】:

以上是关于Laravel Eloquent - 关系上的 firstOrCreate()的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent - 通过用户模型上的方法对用户关系进行排序

Laravel Eloquent 关系方法语法

Laravel Eloquent发现并返回两种不同的类型?

如何在 Laravel/Eloquent 中获得完整的关系

深入理解 Laravel Eloquent——模型间关系(关联)

laravel 返回与 eloquent 和 laravel 的关系