To start I have a $cart that returns a collection.
Example:
Collection {#391 ▼
#items: array:2 [▼
"027c91341fd5cf4d2579b49c4b6a90da" => CartItem {#393 ▼
+rowId: "027c91341fd5cf4d2579b49c4b6a90da"
+id: "1"
+qty: 3
+name: "item 1"
+price: 9.99
+options: CartItemOptions {#392 ▶}
-associatedModel: null
-taxRate: 21
}
"370d08585360f5c568b18d1f2e4ca1df" => CartItem {#394 ▶}
]
}
I'm using the id to to match the Items
$cart = \Cart::content()->pluck('id', 'qty');
$items = Item::whereIn('id', $cart)->get();
Then attaching the items to the order
$order->items()->attach($items, [
'qty' => ???
]);
How can I also include the qty when attaching? Items attach as expected but also need the qty.
Update: As pointed out by Twitter user AnellyBot, you can achieve this by passing a dictionary to the attach method:
$order->items()->attach(
Cart::contents()->mapWithKeys(function ($item) {
return [
$item->id => ['qty' => $item->qty]
];
})->all()
);
The original answer said that you can't do this with the attach method. That's obviously wrong.
I'm leaving the original answer here, since the code is still technically correct.
Eloquent's attach method does not allow adding extra attributes that are different for each attached record.
You'll have to either attach each record directly, or manually insert the records in the pivot table yourself.
Here's some code to get you started:
$order->items()->newPivotStatement()->insert(
Cart::content()->map(function ($item) use ($order) {
return [
'order_id' => $order->id,
'item_id' => $item->id,
'qty' => $item->qty,
];
})->all()
);
Adapt it to your needs.
Related
unable to delete all nested branches where "product" => null
Have a query
$cartWhere['user_id'] = $user_id;
$cartWhere['site_id'] =$currentSite->id;
$item = Cart::select('product_id','quantity')->with(['product' => function($product) use ($search){
$product->join('product_translations', 'products.id', '=', 'product_translations.product_id');
$product->where( 'product_translations.name', 'LIKE','%'.$search.'%');
},'product.manufacturer:id,name'])
->where($cartWhere)->get();
then I receive collection that has all filtered carts but some of these carts have a relation with product => null
1 => App\Models\Cart {#736 ▼
...
#original: array:2 [▼
"product_id" => 1
"quantity" => 2
]
...
#relations: array:1 [▼
"product" => App\Models\Product {#785 ▶}
]
}
2 => App\Models\Cart {#736 ▼
...
#original: array:2 [▼
"product_id" => 2
"quantity" => 2
]
...
#relations: array:1 [▼
"product" => null
]
}
sorry for my English
You can filter them from the results using the collections filter() method
$item = Cart::select('product_id','quantity')
->with(['product' => function($product) use ($search) {
$product->join('product_translations', 'products.id', '=', 'product_translations.product_id');
$product->where( 'product_translations.name', 'LIKE','%'.$search.'%');
}, 'product.manufacturer:id,name'])
->where($cartWhere)
->get()
->filter(function ($cart) {
return $cart->product !== null;
});
Along with with you should use whereHas. So the result will not include any relation with null value. So this way you can also avoid the extra filter method used.
I have this collection
Collection {#611
#items: array:1 [
0 => Payeur {#605
#guarded: array:1 [
0 => "id"
]
#attributes: array:11 [
"id" => 1
"prenom_payeur" => "aymen"
"nom_payeur" => "larabi"
"mobile_payeur" => "non"
"telephone" => 230493212
"observation" => "jeflolena"
"adresse" => "jdjfnrll"
"event_id" => 1
"adherent_id" => 3
"created_at" => "2019-12-22 14:57:43"
"updated_at" => "2019-12-22 14:57:43"
]
}
]
}
and I want to get the nom_payeur attributes from this collection. I did this many times before and I don't know why I get this error:
(Property [nom_payeur] does not exist on this collection instance.)
I'm trying to get the attributes by doing this: $payeur->nom_payeur , $payeur is the collection.
Please help.
try this hope its help
you have the collection and you try to access this property that is not possible beacuse in collection you can n't access element or attribute directly you have to use the array of index for this to access the poperty.
$payeur -> is collection this is incorrect way to access the property.
try this to access the attribute property.
$payeur[0]->nom_payeur
I have the following method of my cart class:
public function add($productId) {
$product = Product::where('id', $productId)->first();
if (!$product) {
return false;
}
if ($this->items->has($productId)) {
$this->items->$productId->qty++;
} else {
$this->items->push([$productId => [
'name' => $product->title,
'price' => $product->price,
'is_sale' => $product->is_sale,
'sale_price' => $product->sale_price,
'sale_percent' => $product->sale_percent,
'can_use_promocode' => $product->can_use_promocode,
'qty' => 1,
]
]);
}
$this->save();
return true;
}
But on dump($cart) in controller, I got this:
+items: Collection {#176 ▼
#items: array:1 [▼
0 => {#171 ▼
+"2": {#164 ▼
+"name": "101 роза"
+"price": 4999
+"is_sale": 0
+"sale_price": null
+"sale_percent": null
+"can_use_promocode": 1
+"qty": 1
}
}
]
}
But I need to:
+items: Collection {#176 ▼
#items: array:1 [▼
2 => {
+"name": "101 роза"
+"price": 4999
+"is_sale": 0
+"sale_price": null
+"sale_percent": null
+"can_use_promocode": 1
+"qty": 1
}
]
}
In this case, I thought that $this->items->push([$productId => ...] will push the key => value pair to collection, but collection creates its own pair, and my pair goes into collection pair. (idk how to describe it correctly, but I think you understand me :) )
Use the put() method instead:
->put($key, $data)
The put method sets the given key and value in the collection
I'm pretty new to Eloquent and I'm having issues wrapping my head around something.
Basically I have a table which I'm recursively grabbing children from within the same table.
public function children() {
return $this->hasMany(static::class, 'parent_org_id');
}
public function childrenRec()
{
return $this->children()->with('childrenRec');
}
Where childrenRec is a recursive call to all children based on 'parent_org_id'
I'm calling it from the following in a static function, as of right now I only want the id and the name_en of the org
self::select('id','name_en')->where('parent_org_id','=',0)->with('childrenRec')->get()->toArray();
which is grabbing the top level org (my top level org has a parent_org_id of 0).
My issue is that in the recursively grabbed children it doesn't limit it to the id and the name_en
My question boils down to:
How can I select only certain columns from my recursive child calls, as well is this the 'proper' way of doing things?
My returned array looks like this.
array:1 [▼
0 => array:4 [▼
"id" => 1
"name_en" => "Org Unit"
"org_type" => null
"children_rec" => array:2 [▼
0 => array:27 [▼
"id" => 2
"name_en" => "My First Orgunit."
"code" => null
"abbreviation" => null
"address1" => "222 Street Street"
"address2" => null
"city_id" => 1
"province_id" => 14
"postalcode" => "C161L7"
"country_id" => 38
"contact_name" => null
"contact_title" => null
"email" => "test#test.com"
"fax" => "902-555-5555"
"phone1" => "5125125125125"
"phone2" => null
"org_type_id" => 1
"parent_org_id" => 1
"ref_id" => 79
"has_users" => 1
"created_at" => "2016-11-02 18:47:55"
"updated_at" => "2016-11-02 18:47:55"
"org_type" => array:4 [▶]
"children_rec" => array:1 [▶]
]
1 => array:27 [▶]
]
]
]
Thanks in advance.
To access the relation query in the with() method you use an array with the name of the relationship as the key and a closure with an instance of QueryBuilder injected.
One 'gotcha' that took me forever to track down a solution to when doing this is, your parent and children queries need to include the key that associates their relationship because the models are attached/associated with each other after both queries are run separately. Those models are associated with each other using the columns defined in the relation on the model. Without the columns used in the association of the models in your query, the related models won't be attached. In your situation it would be:
self::select('id','name_en')
->where('parent_org_id','=',0)
->with(['childrenRec' => function($query) {
return $query->select('id', 'name_en', 'parent_org_id');
}])
->get()
->toArray();
If you don't include the parent_org_id in the subquery the relationships won't get attached.
Docs
Try this:
public function childrenRec()
{
return $this->children()->with(['childrenRec' => function($query){
$query->select('id','name_en');
}]);
}
Here is what I try to do:
$q = Question::where('id',$id -> id)->get();
$q[] = $q->push([ 'test' => true]);
dd($q);
This will output:
Collection {#220 ▼
#items: array:3 [▼
0 => Question {#225 ▶}
1 => array:1 [▼
"test" => true
]
2 => null
]
}
So 'test' => true will append as a new key, but I want to insert it in Question so latter I can access to it like this with foreach $q -> test
So here is how I want access to item:
#foreach($q as $qq)
{{ $qq->test }}
#endforeach
It can be done by using setAttribute() function of Eloquent Model (https://github.com/illuminate/database/blob/master/Eloquent/Model.php).
As You can see it stores data in protected $attributes using setAttribute(), and when we do $SomeModel->some_field it uses magic method __get() to retrieve item by association from attributes array.
Here is the resolution to Your question:
$Question = Question::find($id);
$Question->setAttribute('test', 'blablabla');
Apart from setAttribute(), you can use put() refer to this post for one item. And map() for many items, refer to this post.