Do I need a repository for Eloquent??

All will take. Recently I read several articles on the implementation of the repository pattern in Laravel framework. How to implement the pattern became clear to me, but it's unclear whether the meaning of this pattern, if all the examples as a point of access to the database using Eloquent?

I understand the point of creating a repository for QueryBuilder. It just still allows you to separate your query logic from the business logic you put in my services, but whether it is in Artive Record? I thought that the Eloquent model already, in principle, by themselves, perform some kind of repository? That is, they are your basic user-friendly interface that can extend the local and global scopami. And if it can be done, but it is unclear why they would need a separate layer that will do the same...

They say that this will allow to change the type of data storage. But I'm also not entirely clear. After all, if I use ORM, it opredeliat to some extent the format of the output data. For example, the adjacent table are Eloquent nested objects in the object. That is, even when you output the array, we get a nesting, which will be incompatible even with the QueryBuilder, and the adaptation of big date and wrap it to some output format is a thankless job. And if you think about Redis, most of the projects in principle cannot be transferred to a non-relational database.

So here's the question. From the foregoing it is unclear to me why the repository pattern on top of Eloquent. Can someone share their opinion about this and about when you really become a useful repository, even if they operate not through Eloquent, and using native SQL queries or something like that...
March 12th 20 at 08:41
5 answers
March 12th 20 at 08:43
The point is that if you 100% do not believe that the pattern repository you need, so you do not need. Otherwise you will get an extra layer of abstraction, a mountain of copy-paste and duplication of the same Eloquent.

Suggest a workshop on DDD (the second part about the repository), explains why the need for a lot of things.
Take the opportunity to ask a question. And where such logic should encapsulate? In the repository - Yes, like no, he's not really in the model itself - is also nonsense. Anyway in General I can not understand where to write the logic like this? (When you need to produce something a little more than just the record in the database) it is Possible to create Event for this, but also doubtful somehow.
protected $uploadService;

 public function __construct(User $user, FileUploadContract $uploadService)
{
 $this->user = $user;
 $this->uploadService = $uploadService;
}

 public function updateUserImage(UploadedFile $image)
{
 $oldImageName = $this->user->profile_image;

 $newImageName = uniqid("", false) . '.png';
 $this->user->profile_image = $newImageName;

 try {
 DB::transaction(function() {
$this->user->update();
});
 $this->uploadService->upload($image, $newImageName, $oldImageName);
 } catch (Exception $e) {
 abort(503, $e->getMessage());
}
 }
- Christa.Stamm commented on March 12th 20 at 08:46
@Christa.Stamm, for example, in the \App\Services\User\UpdateImageService or the \App\Services\UserService. You can register it in the service container, transfer dependence, and in the controller call through the service container. - Bobbie.Trembl commented on March 12th 20 at 08:49
@Bobbie.Trembl, thus fine?
class UserService extends UserServiceContract
{
 protected $user;
 protected $uploadService;
 //Constructor definition $b user $uploadService sewn in an abstract class UserServiceContract like this:
/*
public function __construct(User $user, FileUploadContract $uploadService)
{
 $this->user = $user;
 $this->uploadService = $uploadService;
}
*/
 public function updateUserImage(UploadedFile $image): void
{
 $oldImageName = $this->user->profile_image;

 $newImageName = uniqid("", false) . '.png';
 $this->user->profile_image = $newImageName;

 try {
DB::transaction(function(){
$this->user->update();
});
 $this->uploadService->upload($image, $newImageName, $oldImageName);
 } catch (Exception $e) {
 abort(503, $e->getMessage());
}
}
}


The whole thing is logged in the container like so:
app()->bind(UserServiceContract::class, function($app, $parameters) {
 return app()->makeWith(UserService::class, $parameters);
});

app()->when(UserService::class)->needs(FileUploadContract::class)
 ->give(function() {
 return new AvatarUploadService(config('images.user_avatar_dir'));
 });


And eventually the controller is used like this:
public function postUserProfileImage(UserUpdateImageForm $request)
{
 $userService = app()->makeWith(UserServiceContract::class, ['user'=>auth()->user()]);
 $userService->updateUserImage( $request->file('profile_image') );

 return redirect()->back();
}
- Christa.Stamm commented on March 12th 20 at 08:52
@Christa.Stamm, UserServiceContract must be an interface. The challenge of this contract (interface) from the service container you bendice a concrete implementation of the UserService.

The logic is that you're not interested in the details of the operation of the service, but you know exactly what takes, and that returns the implemented interface. Thus you can always prebendal the same interface, different implementation.

If you need to make some common part of all classes in an abstract class, you name it AbstractUserService. - Bobbie.Trembl commented on March 12th 20 at 08:55
@Bobbie.Trembl, got it, thanks. - Christa.Stamm commented on March 12th 20 at 08:58
@Bobbie.Trembl, Hey, if logic is not entirely suspended, as a download pictures. For example, when creating a model you need together with the direct entry fields and save the model to load the image from the field to the server? If you delete a model, respectively, and the disk file delete and stuff like that? Where such things, then, to encapsulate? To hang the observer in creating/deleting and it has to catch the file to perform the action and continue to pass on the request? - Christa.Stamm commented on March 12th 20 at 09:01
@Christa.Stamm, Yes - Bobbie.Trembl commented on March 12th 20 at 09:04
March 12th 20 at 08:45
Here's another article https://m.habr.com/post/316836/
I personally refused to repository with eloquent
March 12th 20 at 08:47
Eloquent perfectly fulfills its tasks simple and more or less efficient ORM for projects with CRUD and such.
Of course often need more complicated queries and they are isolated or in scope in the model or in separate classes, which bildet requests.
When tasks become even more difficult when you have to share all our model on the read and write portions, Eloquent already beginning podbeshivat :) Plus the inability to separate the logic of the model class from the logic of its storage in the database begins to strain at all more complicated models one row in the database. In the end, in those projects in which we want to separate Domain logic from everything else(including the database) is much more profitable to move away from him.
All these repositories we need to do just that, to abstract and separate the logic of storing objects domain logic anywhere. And eloquent it is almost impossible. I will analyze in detail in the book that there is already the advertise - https://leanpub.com/architecture-of-complex-web-ap...

Highlight the classes to a query building - it is quite normal for projects with Eloquent. Here only it is desirable not to get involved. Sometimes people suffer terribly with these lokomoskaj the builders, when corny is easier to write a raw SQL query. This usually applies to all reports where a lot of interesting aggregation groups, etc.
March 12th 20 at 08:49
Eloquent - this is a repository for QueryBuilder
so I think so, but still opensorce projects sometimes see this extra, unnecessary abstraction on top of the ORM repository...) - josephine_Schad commented on March 12th 20 at 08:52
@josephine_Schad, everyone says the extent of his experience.
Unfortunately, many people often make mistakes when writing code using functions for functions. - maxwell commented on March 12th 20 at 08:55
March 12th 20 at 08:51
Odd you chaotically written and mixed different things.
In larval is separately useful tools/wrappers to work with the database, and a separate thing is the Eloquent ORM on the structure of the principles (anti or not) Paterna ActiveRecord.
So this wrapper on the database you use and follow/use convenient you approach/patern to the organization of the models. Overall, I suggest to move away from Eloquent if the project will be developed in the future and/or if it will lead a few people, as it begins the fermentation process models-properties and methods and Eloquent on the project that eventually leads to the complication of debugging, development, change/add edit properties etc. Of course if the project is simple, without super logic and you know what would happen next, everything is simple, you can not steamed.
Well, I advise you to study and read the comments on the toaster directly on this subject:
https://toster.ru/answer?answer_id=1127442#answers...
Yeah. Go from eloquent and I net sql 2ะบ18 :)
Working on four large projects in a team of three people. Eloquent does not interfere. On the contrary, even largely save the situation, starting with the fact that you have a specific model with specific properties. But if someone needs to expand, this is done very easily. - maxwell commented on March 12th 20 at 08:54
@maxwell, well, where I wrote that we need to abandon Eloquent in favor of pure sql? I just noted that it is possible to use a different ORM or write your approach and calmly using the QueryBuilder it is not tied to Eloquent. - Allene5 commented on March 12th 20 at 08:57
@Allene5, read into your own words:
Overall, I suggest to move away from Eloquent if the project will be developed in the future and/or if it will lead a few people, as it begins...

Here is where you said it. - maxwell commented on March 12th 20 at 09:00
@maxwell, well, actually everywhere is recommended to use ActiveRecord for small and medium projects. so his words have some truth... - josephine_Schad commented on March 12th 20 at 09:03
@josephine_Schad, Laravel uses Eloquent instead of AR. This type of competitors. - maxwell commented on March 12th 20 at 09:06
@josephine_Schad, here's one, a Russian Seigneur his book writes about hayload projects at Lara, one of which he works: https://leanpub.com/principles-of-creating-big-app... - maxwell commented on March 12th 20 at 09:09
@maxwell, link broken - Sasha.Feeney commented on March 12th 20 at 09:12
@Sasha.Feeney, the author probably hid it because he still writes it.
Here's a link to the author: https://t.me/roxane_Web32 - maxwell commented on March 12th 20 at 09:15
https://leanpub.com/architecture-of-complex-web-ap... here's the correct link. Thanks for the PR :) - roxane_Web commented on March 12th 20 at 09:18

Find more questions by tags Laravel