My main model Tag
has a one-to-many relationship with Product
where one Tag
can have many Products
assigned to them via tag_id
relationship on the DB.
On my edit view, I am allowing users to edit the tag products
. These products can be added/edited/deleted on the form request.
Each product
field on the form is picked up from a request()
array. Eg: request('title'),request('price')
.
I have set $title[$key]
as the request('title')
array for example.
My thoughts next, was to loop through each of the products
for this tag
and updateOrCreate
based on the request data. The issue here, is that there's no way of detecting if that particular product
was indeed needing updated.
TagController - Update Product Model (One-to-Many)
foreach($tag->products as $key => $product){
Product::updateOrCreate([
'id' => $product->id,
],
[
'title' => $title[$key],
'price' => $price[$key],
'detail' => $detail[$key],
'order' => $order[$key],
'tagX' => $tagX[$key],
'tagY' => $tagY[$key],
'thumb' => $img[$key],
]);
}
For the initial tag
update, I have set an if
statement which works great (albeit messy) for the main tag img
.
TagController - Update Tag Model
//Update the tag collection
if($request->hasFile('img')) {
$tag->update([
'name' => $name,
'hashtag' => $hashtag,
'img' => $imgPub,
]);
} else{
$tag->update([
'name' => $name,
'hashtag' => $hashtag,
]);
}
Is there a better way to determine if the product
fields were updated on the request?
Ideally I would like the user to be able to add/remove or edit products
from the tag
edit request, but not delete existing product images if they have not been updated. Thanks!
As per my view, you are on the wrong track. Tagging relationship should be Many To Many.
You must check about sync()
method of Laravel in ManyToMany relationship. Please check this: https://laravel.com/docs/5.8/eloquent-relationships#many-to-many
Notes: Please add codes as per your business logic.
Product.php
public function products(){
return $this->belongsToMany( 'App\Product', 'product_tags', 'tag_id', 'product_id');
}
Tag.php
public function tags(){
return $this->belongsToMany( 'App\Tag', 'product_tags', 'product_id', 'tag_id');
}
ProductController.php
public function update(Product $products, Request $request){
//update the product
$products->update($request->all());
//attach new tags to the product
$products->tags()->sync($request->input('tag_list'));
return redirect('articles');
}
Normally I do something similar on the frontend side
<div class="product">
<!-- For Products that may be edited -->
<input type="hidden" name="id" value={{$product->id??0}}>
<input type="hidden" name="action" value="update">
<input type="text" name="title" value={{$product->title}}>
...
</div>
<div class="product">
<!-- For New Products -->
<input type="hidden" name="id" value=0>
<input type="hidden" name="action" value="add">
<input type="text" name="title" value="New Title">
...
</div>
<div class="product">
<!-- For Deleted Products -->
<input type="hidden" name="id" value={{$product->id}}>
<input type="hidden" name="action" value="delete">
<input type="text" name="title" value="New Title">
...
</div>
Create the json (array of product objects) payload using javascript and send ajax request to the backend
[{'id':101,'title':'product 1','action':'update'},
{'id':102,'title':'product 2','action':'update'},
... ,
{'id':201,'action':'delete'},
{'id':202, 'action':'delete'},
... ,
{'id':0,'title':'new product 1','action':'add'},
{'id':0,'title':'new product 2','action':'add'}]
Now on the backend side, loop through the list of products and check for action. Depending on the action, take necessary step.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.