Will the 'sometimes' rule be supported in the future / partial updates? #65
Replies: 5 comments
-
I've tried a few approaches for the partial update feature:
class ProductData extends DataTransferObject
{
public function __construct(
public string|Undefined $name = new Undefined,
public bool|Undefined $available = new Undefined,
) {
}
public static function fromRequest(ProductRequest $request): ProductData
{
return new self(...$request->only([
'name',
'available'
])->toArray());
}
} class DataTransferObject
{
public function collection(): Collection
{
$data = new Collection();
$class = new ReflectionClass(static::class);
$properties = $class->getProperties(ReflectionProperty::IS_PUBLIC);
foreach ($properties as $reflectionProperty) {
// Skip static properties
if ($reflectionProperty->isStatic()) {
continue;
}
$value = $reflectionProperty->getValue($this);
// Skipping Undefined values.
if ($value instanceof Undefined) {
continue;
}
$data->put($reflectionProperty->getName(), $reflectionProperty->getValue($this));
}
return $data;
}
public function has($key): bool
{
return $this->collection()->has($key);
}
public function only($keys)
{
return $this->collection()->only($keys);
}
public function toArray(): array
{
return $this->collection()->toArray();
}
} Was not sure if I should add more details about the partial API update thing, as maybe that is not the scope of the package but I thought it might help the discussion. |
Beta Was this translation helpful? Give feedback.
-
Played around a bit with this and created a proof of concept as fork cristiancalara@bd32772 (was not sure if I should create a PR without the feature being approved/wanted). While I think adding Undefined to all types is making things a bit harder to read, it might be worth allowing this approach via a flag? This would allow having a 1 to 1 mapping between arrays and data objects - as currently, in an array, we have the concept of undefined, but it's missing in the data object. |
Beta Was this translation helpful? Give feedback.
-
Hi @cristiancalara, I like the idea, though we need to make sure everything keeps working fine. Could you add the PR to this repo? Then I can check it out a bit more. We also need to make sure a |
Beta Was this translation helpful? Give feedback.
-
I bumped into something similar, I think. I allow partial (atomic) updates to models via my controller. The point is to follow the PATCH HTTP verb definition - not to replace an existing resource, but to patch one or more parts of it. This is very simply with simple arrays, as you can simply check if the key exists or not, but I'm trying to use the same with the Data object. The issue is that I need to convert the data object back to an array to update the record in DB. Something like this: class ProductController extends Controller {
public function update(Product $product, ProductData $data)
{
$product->update($data->toArray());
return redirect()->back()->with('success', __('Product successfully updated'));
}
} The problem there is that the request body may not contain all the fields, and so the undefined fields get overwritten with class ProductData extends Data {
public function __construct(
public string $name,
public ?string $description,
) {
}
}
$data = ProductData::from(['name' => 'Foo']);
$data->toArray(); // will produce ['name' => 'Foo', 'description' => null]; I understand how the above makes sense, but it would be great if there was a way to exclude undefined properties altogether when converting back to array. |
Beta Was this translation helpful? Give feedback.
-
Well, it turns out this feature has already been implemented, and is named |
Beta Was this translation helpful? Give feedback.
-
I was wondering if the package plans on supporting the 'sometimes' rule in the future?
The main use case for the above would be to support partial API updates.
Beta Was this translation helpful? Give feedback.
All reactions