Laravel 5:如何将firstOrNew与其他关系字段一起使用

时间:2016-12-01 13:04:23

标签: laravel laravel-5

我有一个CMS,允许用户保存和创建自行车之旅。每个自行车之旅也有类别,使用Laravel的多对多关系利用中间枢轴表来确定。在保存游览时,我们不知道游览是正在编辑的游览还是新游览。

认为我应该使用Laravel的WeakHashMap方法来保存游览,并使用firstOrNew方法来保存类别。但是,所有教程都非常简单地给出了将单个对象传递给函数的示例:

sync

但是当我的$tour = Tour::firstOrNew($attributes); 还包含额外的内容时会发生什么,例如链接到关系表的类别,以及我需要在下一步中保存的内容?例如"(?<![^_])\\d+|\\d+(?![^_])"给出了以下示例:

$attributes

但是如果类别数据与其余游览的数据捆绑在一起会发生什么,而不是使用$categories = [7, 12, 52, 77]; $tour = Tour::find(2); $tour->categories()->sync($categories); 我需要使用find创建游览?我应该在实例化游览时将类别保留在firstOrNew中,然后运行$attributes,然后在保存游览之前取消设置它们,或者......?有没有更好的方法来实现这一目标?

编辑:为了清楚起见,我的示例中的sync变量基本上是捆绑在一起的巡回对象数据 - 就像Laravel / Eloquent系统将使用事务返回它一样belongsToMany方法 - 来自用户的后续修改)。 ie:这是它包含的内容的快照:

$attributes

所有这些属性都是我的tour表中的列名,而不是cat,它通过hasMany关系引用另一个表。在设置此对象类并使用array ( 'id' => 1, 'uid' => '03ecc797-f47e-493a-a85d-b5c3eb4b9247', 'active' => 1, 'code' => '2-0', 'title' => 'Tour Title', 'url_title' => 'tour_title', 'distance_from' => 20, 'distance_to' => 45, 'price_from' => '135.00', 'price_to' => '425.00', 'created_at' => '2013-12-31 15:23:19', 'updated_at' => '2015-07-24 16:02:50', 'cats' => // This is not a column name! array ( 0 => 1, 1 => 7 ), ) 保存它?

之前,是否需要手动取消设置它

我正在寻找最干净的 Laravel 方式吗?

EDIT2:以下是Tours模型中定义的关系:

$tour->save

3 个答案:

答案 0 :(得分:2)

您需要定义Tour模型的$ fillable属性,以便在使用批量分配时告诉他们要考虑哪些属性,以便它将静默忽略类别相关属性。对于前。

<?php
 namespace App;
 use Illuminate\Database\Eloquent\Model;

class Tour extends Model {
     protected $fillable = ['name'] //... other attributes which are part of this model only and laravel will consider only these attributes and ignore category related attributes which you can consider later use.
}

答案 1 :(得分:0)

您可以使用firstOrCreate。使用此方法实际上会保留数据。

$categories = [7, 12, 52, 77];
$tour = Tour::firstOrCreate($attributes)->cats()->sync($categories);

要确保字段是可批量分配的,以便能够使用firstOrCreate方法。因此,要么在$ fillable属性中设置字段名,要么将其放在Tour模型中:

protected $guarded = [];

答案 2 :(得分:0)

由于您已经提到“CMS”和“用户的后续修改”,我猜您从Form获取属性,这意味着您将获得Request对象/集合。 /> 如果是这种情况,那么你可以尝试

$tour = Tour::firstOrCreate($request->except('cats'));  
$categories = [];
foreach($request->get('cats') as $key=>$value){  
    $categories[] = $value;
}
$tour->cats()->sync($categories);  

但是,如果您的$attributes我们根据您的编辑构建为数组(可能对表单数据进行了一些操作),那么在这种情况下您可以尝试:

$tour = Tour::firstOrCreate(array_except($attributes, ['cats']);  
$categories = [];
foreach($attributes['cats'] as $key=>$value){
    $categories[] = $value;
}
$tour->cats()->sync($categories);  

在任何情况下,您必须在模型的$fillable属性中声明质量可分配字段,即Tour

希望这有帮助。