Laravel Eloquent 与孩子一起保存对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24795613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:49:34  来源:igfitidea点击:

Laravel Eloquent saving an object with children

phplaraveleloquent

提问by Jazzy

I am trying to save an orderwith order_itemsbut I am not really finding anything in the docs to support this use case. A hasMany relationship.

我正在尝试保存一个orderwithorder_items但我并没有在文档中找到任何支持这个用例的内容。一个 hasMany 关系。

Basically there is an orderstable with something like id | user_idand an order_itemstable with id | order_id | product_id.

基本上有一个orders类似id | user_idorder_items表和一个表id | order_id | product_id

How can I save()the order and use an array of items at the same time without having to loop over the items and save them individually?

如何同时save()订购和使用一组项目,而不必遍历项目并单独保存它们?

Is this possible?

这可能吗?

Pseudo code assuming $itemsis an array:

假设$items是一个数组的伪代码:

$items = Session::get("cart.items");

$order = new Order;
$order->user_id = Auth::user()->id;
$order->order_items = $items;
$order->save();

回答by Jarek Tkaczyk

What you need for a hasManyrelation is either saveManyor createMany, depending on what's in your $itemsarray:

您需要的hasMany关系是saveManycreateMany,具体取决于您的$items数组中的内容:

// array of attributes:
$items = [
  ['name'=>'item1','price'=>'price1'],
  ...
];

// then createMany:
$order->orderItems()->createMany($items);

This will create new rows in Items table.

这将在Items 表中创建新行。



// array of models:
$items = [
  Item::find($someId),
  Item::find($anotherId),
  // and/or newly instantiated:
  new Item(['name'=>'item1','price'=>'price1']),
  ...
];

// then createMany:
$order->orderItems()->saveMany($items);

This will associate (save) existing models, and create non-existing ones.

这将关联(保存)现有模型,并创建不存在的模型。



Also notice that I use camelCase relation name orderItemsinstead of your order_items. This is an important detail, since Eloquent (Laravel v4) looks for camelCased methods on the model when working with relations (dynamic properties).

另请注意,我使用驼峰式关系名称orderItems而不是您的order_items. 这是一个重要的细节,因为 Eloquent (Laravel v4) 在处理关系(动态属性)时会在模型上寻找 camelCased 方法。

//Order model
public function orderItems()
{
  return $this->hasMany(...);
}

$order->orderItems; // collection
$order->order_items; // collection as well

// --------------------
// BUT
public function order_items()
{
  return $this->hasMany(...);
}

$order->orderItems; // null
$order->order_items; // null

// the only way you can work with relation then, is explicitly use method like:
$order->order_items()->get(); 

回答by lozadaOmr

Probably not the best solution you are looking for, but this should work.

可能不是您正在寻找的最佳解决方案,但这应该有效。

Let's say that the array is named $items, I'm under the impression that you will be saving it into a pivot table. In my example below I also have a 3rd field on item_orderpivot table named item_quantity.

假设数组名为$items,我的印象是您会将其保存到数据透视表中。在下面的示例中,我在item_order数据透视表上还有一个名为item_quantity.

foreach ($items as $item)
{
    $order->items()
    ->attach($item['item_id'], ['item_quantity' => $item['item_quantity']]);
}

Basically you will be looping through the $itemsarray. This will assume that you have defined the relationship on your Order model called items().

基本上你将遍历$items数组。这将假设您已经在名为 的 Order 模型上定义了关系items()

Then use the attach()method

然后使用attach()方法

->attach([insert the item_id], array('3rd field name' => 'value to be inserted')

->attach([insert the item_id], array('3rd field name' => 'value to be inserted')

Finally, if you don't have a 3rd field on your pivot table you could just do

最后,如果您的数据透视表上没有第三个字段,您可以这样做

->attach($item_id)

->attach($item_id)

You can check the example given at the Laravel docs

您可以查看 Laravel文档中给出的示例

Note

笔记

attach()is the method used when the you are only creating a record on the Database, otherwise you need a different method when you want to update.

attach()是仅在数据库上创建记录时使用的方法,否则在要更新时需要不同的方法。

回答by Sojan V Jose

@jareks answer helped in a similar scenario except for a mass assignment exception. so on digging up docs i found that you need to set a guarded or fillable propertyfor mass assignment in latest versions of laravel (4.2).

@jareks 的回答在类似的情况下提供了帮助,除了mass assignment exception。所以在挖掘文档时,我发现您需要 在最新版本的 laravel (4.2) 中为批量分配设置一个受保护或可填充的属性

please refer this along with his answer .

请参考这个和他的回答。

Fillable or guarded properties

可填充或受保护的属性

When creating a new model, you pass an array of attributes to the model constructor. These attributes are then assigned to the model via mass-assignment. This is convenient; however, can be a serious security concern when blindly passing user input into a model. If user input is blindly passed into a model, the user is free to modify any and all of the model's attributes. For this reason, all Eloquent models protect against mass-assignment by default.

创建新模型时,您将一组属性传递给模型构造函数。然后通过批量分配将这些属性分配给模型。这很方便;然而,当盲目地将用户输入传递给模型时,这可能是一个严重的安全问题。如果用户输入被盲目地传递到模型中,则用户可以自由修改模型的任何和所有属性。出于这个原因,所有 Eloquent 模型都默认防止大规模分配。

So set the fillable or guarded properties on your model. Docs and Source

因此,在您的模型上设置可填充或受保护的属性。文档和来源

class User extends Eloquent {

    protected $fillable = array('first_name', 'last_name', 'email');

}