我有一个CMS,允许用户保存和创建自行车旅游。每一个自行车巡演也有类别,这是定义使用Laravel的多到多的关系使用中间枢轴表。在保存旅游的时候,我们不知道这个巡演是正在编辑的,还是一个新的。
我认为我应该使用Laravel的firstOrNew方法来保存旅游,使用sync方法保存类别。但是,所有教程都非常简单地给出了将单个对象传递给函数的示例,如下所示:
$tour = Tour::firstOrNew($attributes);但是,当我的$attributes还包含额外的内容时会发生什么,比如链接到关系表的类别,以及我在下一步需要保存的类别?例如,这个很好的教程给出了以下示例:
$categories = [7, 12, 52, 77];
$tour = Tour::find(2);
$tour->categories()->sync($categories);但是,如果类别数据与巡演的其余部分的数据捆绑在一起,而不是使用find,而是需要使用firstOrNew来创建巡演,会发生什么呢?我是否应该在实例化旅游时将这些类别保存在$attributes中,然后运行sync,然后在保存旅游之前取消它们,还是.?是否有更好的方法来实现这一点?
编辑:要明确的是,在我的示例中,变量本质上是捆绑在一起的$attributes对象数据--就像Laravel/雄辩系统使用belongsToMany方法从事务中返回它一样,用户也会进行相应的修改)。ie:这是它包含的内容的快照:
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
),
)所有这些属性都是我的旅游表中的列名,除了cat,它通过hasMany关系引用另一个表。在设置这个对象类并用$tour->save保存它之前,需要手动取消它吗?
我在找最干净最干净的拉勒维尔方式来做这件事吗?
EDIT2:这里是在旅游模型中定义的关系:
class Tour extends Model
{
protected $guarded = [];
public function cats(){
return $this->belongsToMany('App\TourCategory', 'tour_cat_assignments', 'tour_id', 'cat_id');
}
}发布于 2016-12-01 13:14:43
您需要定义旅游模型的$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.
}发布于 2016-12-01 13:12:05
您可以使用firstOrCreate。数据实际上是使用此方法持久化的。
$categories = [7, 12, 52, 77];
$tour = Tour::firstOrCreate($attributes)->cats()->sync($categories);但是,必须确保字段是可分配的,以便能够使用firstOrCreate方法。因此,要么在$fillable属性中设置字段名,要么将其放在旅游模型中:
protected $guarded = [];发布于 2016-12-03 14:52:55
既然您提到了"CMS“和”用户随后的修改“,我猜您将从Form获得属性,这意味着您将得到一个Request对象/集合。
如果是这样的话,你可以试试
$tour = Tour::firstOrCreate($request->except('cats'));
$categories = [];
foreach($request->get('cats') as $key=>$value){
$categories[] = $value;
}
$tour->cats()->sync($categories); 但是,如果您的$attributes us按照编辑构造为数组(可能对表单数据进行了一些操作),那么在这种情况下,您可以尝试:
$tour = Tour::firstOrCreate(array_except($attributes, ['cats']);
$categories = [];
foreach($attributes['cats'] as $key=>$value){
$categories[] = $value;
}
$tour->cats()->sync($categories); 无论如何,您必须在模型中的$fillable属性(即Tour )中声明大量可分配字段。
希望这能有所帮助。
https://stackoverflow.com/questions/40911409
复制相似问题