Level 6
Hi, is it bad practice to add update method into a repository class?
Hi, in my app there are multi type of products. I implement that like this: Here is product migration:
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('category_id');
$table->unsignedBigInteger('city_id');
$table->nullableMorphs('details');
$table->string('title', 100);
$table->text('description');
$table->timestamps();
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('CASCADE');
$table->foreign('category_id')
->references('id')->on('categories')
->onDelete('CASCADE');
$table->foreign('city_id')
->references('id')->on('cities')
->onDelete('CASCADE');
});
Here is product model:
/**
* Get the details owned the product.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
public function details()
{
return $this->morphTo('details');
}
Here is Animal Product (Details of every sub-products) migration:
Schema::create('animal_products', function (Blueprint $table) {
$table->bigIncrements('id');
.... \ Details of product
$table->timestamps();
});
And here is sub-products model:
/**
* Get the product owned the detail.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
*/
public function product()
{
return $this->morphOne(Product::class, 'details');
}
In this case I am using repository pattern to create and update the product, like this:
// Product controller
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\StoreProductRequest $request
* @return \Illuminate\Http\Response
*/
public function store(StoreProductRequest $request)
{
return response(
$this->repository->create($request->validated() + ['user_id' => auth()->user()->id]),
Response::HTTP_CREATED
);
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\UpdateProductRequest $request
* @return \Illuminate\Http\Response
*/
public function update(UpdateProductRequest $request)
{
$this->repository->update($request->validated());
return response([], Response::HTTP_NO_CONTENT);
}
Now, I read this article. In this article wrote:
your repositories should not have a Save() or Update() method.
But in this article wrote another thing.
...
**
* Updates a post.
*
* @param int
* @param array
*/
public function update($post_id, array $post_data);
Now, in this case what pattern do I use?
Here is my product repository:
class ProductRepository extends Repository
{
/** @inheritDoc */
public function create($data)
{
if (!isCategoryValid($category = Category::find($data['category_id']), Product::class)) {
throw new UnexpectedValueException('The given category is not for Product model or its class not exists.');
}
$dataCollection = collect($data);
$product = (new Product)->forceFill($dataCollection->only(['user_id', 'category_id', 'city_id', 'title', 'description'])->toArray());
$details = $category->class::create($dataCollection->only((new $category->class)->getFillable())->toArray());
$details->product()->save($product);
return $product;
}
/** @inheritDoc */
public function update($data)
{
$dataCollection = collect($data);
$product = Product::find($data['id']);
$result1 = $product->update($dataCollection->only($product->getFillable())->toArray());
$result2 = $product->details()->update($dataCollection->only($product->details->getFillable())->toArray());
return $result1 || $result2;
}
/**
* Get the product category.
*
* @return \Illuminate\Database\Eloquent\Collection|null
*/
public function getCategory()
{
return Product::getTheModelCategory();
}
/** @inheritDoc */
protected function getResourceClass()
{
return Product::class;
}
}
Please or to participate in this conversation.