Open gvanto opened 10 months ago
Hi @gvanto
I think this poses a slight issue. Because you have specified 'source' as the primary key, it is used to determine whether to create or update a row.
The way I would go about this, is to set another column as the primary key, and then you can make source unique.
For example, maybe an ID field?
Hope this makes sense, Many thanks
Hi again @gvanto
While developing events, I can see that there was a bug with validation, it may solve your problem.
Please try installing v1.6.5 and see if the behaviour has changed for you.
Hi @redsquirrelstudio I've updated to 1.6.5 but getting this on import:
Looks like ImportRowProcessed and ImportRowSkipped below should be ImportRowProcessedEvent and ImportRowSkippedEvent ?
Hi @gvanto
My bad, shouldn't update whilst tired, please run composer require redsquirrelstudio/laravel-backpack-import-operation
It should redownload a fixed version of 1.6.5
Many thank for your patience
No worries @redsquirrelstudio and thanks for the quick fix.
I am however still getting same behaviour, the row is getting replaced ie validation not quite working.
Before:
CSV file:
source,target /foo1,/bar1-csv /foo2,/bar2-csv /foo3,/bar3-csv
After: (foo1 replaced with CSV file's version):
Hi @gvanto
I think this poses a slight issue. Because you have specified 'source' as the primary key, it is used to determine whether to create or update a row.
The way I would go about this, is to set another column as the primary key, and then you can make source unique.
For example, maybe an ID field?
Hope this makes sense, Many thanks
Hi @gvanto did you see the above comment?
Hey @redsquirrelstudio,
Saw your comment ...
Couple of points
In most cases ideally records should be skipped and and the user notified of those records, not with a flash message - disappears too quickly - but rather a big red box above the list view showing failed records (I guess this is do-able using your ImportEvents ... which I haven't got around to doing because well, nothing is failing 🤣 )
And in the case of records getting overwritten (ie I selected that option during upload or in code), they can be shown as a notification at the end, as with failed records ...
Again, thanks for an awesome package 👊
Hi @gvanto
Thank you for following up, rest assured I want to get to a solution for this issue :)
To address your points:
I suppose a work around for this would be adding a "don't update" option which would only create records.
Let me know your thoughts about the above,
Thank you for helping to improve the package and it's use cases :D
Hey @redsquirrelstudio,
"The primary key is important as it is used to see whether a row should be updated or created. Therefore it is not validated for uniqueness because otherwise we wouldn't be able to update a row."
I see the issue now ...
"I suppose a work around for this would be adding a "don't update" option which would only create records." This would be nice yep!
Yes absolutely agree with points 1 and 2.
Things can get complicated if allowing the user (note: not the developer), to select what happens on import fail (this would require selecting "skip/not" on every rule!) I think it kind of defeats the purpose of having validation at all perhaps - a better approach might be to let the developer create a '{modelName}ImportRequest' class and define import-specific rules there (?). IMHO giving users too many options/choices just overcomplicates things and inevitably they will screw things up 🤣 This also forces them to ensure their import data is clean to begin with ...
What would be great (especially if you have some examples in your README), is how to implement the "showing which rows failed to import after the import" part ... I am not entirely sure how to do this (show a message box with feedback info back on the list view, after returning from the import - guess it involves adding stuff to flash and then showing them if they exist ...), as I'm still quite a backpack noob (but loving this package and ones like yours, making building great UIs a breeze!)
Hope you have a great day Lewis!
Hi @redsquirrelstudio
I've also just tested import validation for 'target' field of my Redirect class, seems its also not working as expected.
The following CSV file uploaded ALL rows (redirects table empty before upload). The first row should have been skipped, since 'bar1-csv' does not meet validation criteria.
source,target /foo1,bar1-csv /foo2,/bar2-csv /foo3,/bar3-csv
protected function setupImportOperation()
{
// https://github.com/redsquirrelstudio/laravel-backpack-import-operation/issues/4
$this->disableUserMapping();
CRUD::setValidation(CreateRedirectRequest::class);
CRUD::addColumn([
'name' => 'source',
'label' => 'Source',
'type' => 'text',
'primary_key' => true
]);
CRUD::addColumn([
'name' => 'target',
'label' => 'Target',
'type' => 'text',
]);
}
CreateRedirectRequest rules:
public function rules()
{
return [
'source' => [
'required',
'unique:redirects',
function (string $attribute, mixed $value, Closure $fail) {
if (!Str::startsWith($value, '/')) {
$fail("The {$attribute} must start with '/'.");
}
},
],
'target' => [
'required',
function (string $attribute, mixed $value, Closure $fail) {
if (!Str::startsWith($value, '/') && !Str::startsWith($value, 'https://')) {
$fail("The {$attribute} must start with '/' or 'https://'.");
}
},
],
];
}
And with empty value for 'target', it still uploads the record:
source,target /foo1,bar1-csv /foo2,/bar2-csv /foo3,/bar3-csv /foo4,
using package 1.6.5 btw
And with empty value for 'target', it still uploads the record:
source,target /foo1,bar1-csv /foo2,/bar2-csv /foo3,/bar3-csv /foo4,
using package 1.6.5 btw
Hi @gvanto, could you try v1.6.7 please
With many thanks and warm regards,
Lewis
hi @redsquirrelstudio
Updated to 1.6.7 and both rows still upload:
A note on the validation during upload, think there might still be a slight bug (I updated to 1.6.4) as I have a rule that my redirect.source should be unique (this validation works as it should with the single record create form in backpack), but I am finding that it does not skip rows that violate this rule, it simply uploads them (replacing old record).
My RedirectCrudController:
My RedirectRequest class:
Before import:
Import CSV: source,target /foo1,/bar-dupe-test-4 /foo2,/bar2 /foo3,/bar3
After import (notice /foo1 has been updated instead of skipped)