Propel 1.6 Inserting and updatin many-to-many relationships - propel

I have three tables
1 - Items
2 - Suppliers
3 - Item_Suppliers
Third is crossref table between items and supplier.
My question is how can I save and update item_supplier table with propel.
On items page customer can select multiple suppliers and than it will be sent to be saved in db. Is there any way to save it into DB with default Propel 1.6 functions. This is how data is coming from user interface.
array:8 [
"Name" => "Strawberry"
"CategoryId" => "2"
"suppliers" => array:3 [
0 => "1"
1 => "2"
2 => "3"
]
"Points" => "20"
"Description" => "Strawberry Description"
]

You should set the isCrossRef="true" attribute in the schema for your Item_Suppliers relationship:
<table name="Item_Suppliers" isCrossRef="true">
<column name="ItemId" type="integer" primaryKey="true"/>
<column name="SupplierId" type="integer" primaryKey="true"/>
<foreign-key foreignTable="Item" onDelete="CASCADE" onUpdate="CASCADE">
<reference local="ItemId" foreign="Id"/>
</foreign-key>
<foreign-key foreignTable="Supplier" onDelete="CASCADE" onUpdate="CASCADE">
<reference local="SupplierId" foreign="Id"/>
</foreign-key>
</table>
Then updating the related models is simple with the generated method:
$suppliers = SupplierQuery::create()->filterById( $input["supplier_ids"] )->find();
$item->setSuppliers( $suppliers )->save();

Related

How to translate custom values for all indexes of array based form input fields for validation in Laravel

Take this array based form input fields that allows user to add and remove items with type (simple or complex) and complex infos:
<div class="item">
<div>
<h2>Type</h2>
<label><input type="radio" name="data[0][type]" value="simple"> Simple ABC stuff</label>
<label><input type="radio" name="data[0][type]" value="complex"> Complex XYZ stuff</label>
</div>
<div class="complex"> <!-- it will be visible only when type is "Complex XYZ stuff" -->
<h2>Complex info</h2>
<input type="text" name="data[0][complex_info]"/>
</div>
<button class="remove">Remove item</button>
</div>
<div class="item">
<div>
<h2>Type</h2>
<label><input type="radio" name="data[1][type]" value="simple"> Simple ABC stuff</label>
<label><input type="radio" name="data[1][type]" value="complex"> Complex XYZ stuff</label>
</div>
<div class="complex"> <!-- it will be visible only when type is "Complex XYZ stuff" -->
<h2>Complex info</h2>
<input type="text" name="data[1][complex_info]"/>
</div>
<button class="remove">Remove item</button>
</div>
<button class="add">Add item</button>
When user selects the "Complex XYZ stuff" type, then "Complex info" input should be required. So we set this form request rule in Laravel 6.x:
public function rules() {
return ['data.*.complex_info' => 'required_if:data.*.type,complex'];
}
When the required_if validation rule fails, we get the error message The :attribute field is required when :other is :value. that with the filled parameters should result in a message like this: The Complex info field is required when Type is Complex XYZ stuff. (expected message).
The following validation.php language file would work for a form of 2 items:
return [
/* ... */
'values' => [
'data' => [
0 => [
'type' => [
'simple' => 'Simple ABC stuff',
'complex' => 'Complex XYZ stuff',
]
],
1 => [
'type' => [
'simple' => 'Simple ABC stuff',
'complex' => 'Complex XYZ stuff',
]
],
]
]
];
And I need it to work for a form with an indefinite number of items (all indexes), so I thought about using the * wildcard like:
return [
/* ... */
'values' => [
'data' => [
'*' => [
'type' => [
'simple' => 'Simple ABC stuff',
'complex' => 'Complex XYZ stuff',
]
],
]
]
];
But it doesn't work, the :value parameter of the required_if validation rule's error message is not properly translated: The Complex info field is required when Type is complex. (actual message).

How to Store Data from select html tag to DB and display it...Laravel

Laravel
I have 3 tables
1- users => id + name + email + password
2- categories => id + name
3- category_user => user_id + category_id
I want the users to choose their favorite categories so that only the articles for that category appear.
here the page to select category:
<div class="form-group">
<label for="body">Category</label>
<select name="categories[]" id="" multiple>
#foreach ($categories as $category)
<option value="{{$category->id}}">{{$category->name}}</option>
#endforeach
</select>
how can I store this data in the category_user table? (with validate)
Also, how can I display only articles belonging to the selected categories?
If you dump and die your request data in controller, you will see categories as an array. you can iterate through categories by a foreach loop and save it to category_user table. Don't forget to use current user id as user_id.
foreach ( $request->categories as $categoryId ) {
CategoryUser::create( [ 'user_id' => auth()->user()->id, 'category_id' => $categoryId ] )
}
For display need some more information about articles table. Is one article belongs to one or many category?

Array to string conversion error when multiple file upload in Laravel 5.8.38

I have an Array to string conversion error, when trying to realize multiple upload files function in Laravel 5.8.38
Cant find any decision about it
In blade form I have simple thing:
<form class="form-horizontal" action="{{route('admin.estates.store')}}" method="post" enctype="multipart/form-data">
{{ csrf_field() }}
<label for="estate_image" class="mt-4">Images</label>
<input type="file" name="estate_image[]" multiple>
<input class="btn btn-primary" type="submit" value="Сохранить">
<input type="hidden" name="created_by" value="{{Auth::id()}}">
</form>
In store function I have:
The function creates an estate(one property). If user adds some images for it, we adds this images in local path and adds them in database
if I comment $estate = Estate::create($request->all()); it works fine
but in this case estate doesnt adds in database
public function store(Request $request)
{
$estate = Estate::create($request->all());
if($request->hasFile('estate_image')) {
foreach ($request->file('estate_image') as $image) {
// do some image resize and store it on local path
$filename = time() . '.' . $image->getClientOriginalExtension();
$location = public_path('images\\' . $filename);
Image::make($image)->resize(800, 400)->save($location);
// add image info in database
$estateimage = new EstateImages();
$estateimage->image_path = $location;
$estateimage->image_alt = 'testalt';
$estateimage->save();
}
}
}
Am array I have from input
array:5 [▼
"name" => array:2 [▼
0 => "image1.jpg"
1 => "image2.jpg"
]
"type" => array:2 [▼
0 => "image/jpeg"
1 => "image/jpeg"
]
"tmp_name" => array:2 [▼
0 => "C:\OSPanel\userdata\php_upload\phpCB51.tmp"
1 => "C:\OSPanel\userdata\php_upload\phpCB52.tmp"
]
"error" => array:2 [▼
0 => 0
1 => 0
]
"size" => array:2 [▼
0 => 164808
1 => 58217
]
]
As understand, foreach doesnt start, but dont understand why (tried to delete all code in foreach, and leave there just simple echo 'Hello!'; , have the same error.
Saw the same problems in StackOverflow, but any of it helped me...
The problem was in first line
$estate = Estate::create($request->all());
So, from blade I receive a name="estate_image[] data which is an array, and Laravel tried to adds an array in database cell. In database cell cold be added just string value and through that, I had that error.
Solve it, by deleting this column from database and deleting this from $fillable variable in main model.
Quite stupid and easy thing from me, but hope, this answer helps someone. :-)

Laravel Validating Values in Array in List of Values

This must be a simple question, but unable to find what I am doing wrong. I have a form (shown below) with a multi-select input. It gets sent to the validator as an array. I want to make sure the values selected in the client-side are in the pre-defined list of values.
<form>
<select multiple name="names[]">
<option value="Jerry">Jerry</option>
<option value="Susan">Susan</option>
<option value="Tim">Tim</option>
</select>
</form>
public function postNames(Request $request)
{
$this->validate($request, [
'names.*' => 'in:Jerry,Susan,Tim',
]);
}
When I open the dev tools in the browser and change the value of them and then submit the form, the validator lets it pass even though the name in the request is not in the list as defined in the validator.
Thank you.
UPDATE:
When I dump the request it looks like this.
+request: Symfony\Component\HttpFoundation\ParameterBag {#52 ▼
#parameters: array:1 [▼
"names" => array:1 [▼
0 => "Robert"
]
]
}

Laravel do check selected items from array on html select as multiple feature

After get all categories and user selected categories for selected post with this result:
$content_categories = ContentCategories::all()->pluck('title', 'id');
Collection {#209 ▼
#items: array:3 [▼
1 => "laravel"
2 => "nodejs"
3 => "php"
]
}
$selected_categories = $manage_content->categories()->get()->pluck('title', 'id');
Collection {#223 ▼
#items: array:2 [▼
1 => "laravel"
2 => "php"
]
}
I'm trying to implement this result on html select and do check selected items when we have in $selected_categories, this code only show $content_categories and can not be check items with $selected_categories by default
{{
Form::select('categories[]',
$content_categories,
$selected_categories,
array('multiple'=>'multiple'))
}}
result:
<select class="multiselect-success" multiple="multiple" name="categories[]">
<option value="1">laravel</option>
<option value="2">nodejs</option>
<option value="3">php</option>
</select>
Get IDs of selected categories without titles:
$selected_categories = $manage_content->categories()->pluck('id');
Or use keys() to get keys only:
Form::select('categories[]', $content_categories, $selected_categories->keys(), array('multiple'=>'multiple'))

Resources