Is it good practice to distribute Laravel models across multiple layers?

I am reworking a project on Laravel 5.1

I understand that the old classes have become much more complicated and no longer follow the principle of “single responsibility”.

So, I plan to do the following:

<?php class User extends Model { } class SocialUser extends User { } 

So I have a few questions

  • Can this be achieved?
  • If so, does the SocialUser class link to the same database table as the users and does it conflict with the user model itself?
  • Is this good design practice in the first place? Or am I using traits better?

Thanks.

+6
source share
2 answers

What you do (expanding the User model) is excellent, and the approach that I use myself in projects.

For example, if the Im building application has functions similar to a store, then I can create a Customer model that extends my User model and contains, for example, relations related to the order:

 class Customer extends User { public function orders() { return $this->hasMany(Order::class, 'customer_id'); } public function worth() { return $this->orders()->sum(function ($order) { return $order->total(); }); } } 

In a recent project, Ive worked on email functionality and created a Recipient class that extends the User model to add campaign-related methods:

 class Recipient extends User { public function campaigns() { return $this->belongsToMany(Campaign::class, 'recipient_id'); } } 

Since both of these classes extend the User model, I get all of these (and pronounced) methods:

 $customers = Customer::with('orders')->get(); 

While you are setting up a table in your base User model, any classes that inherit it will use the same table, although the model can be named differently (i.e. Customer , Recipient , Student , etc.).

+2
source

IMHO I would choose a repository template. This makes a lot of sense in your situation.

I would do the following:

 interface UserRepository { public function find($id); public function getAll(); public function create(array $attributes); public function destroy($id); //you get the point } class CoreUserRepository implements UserRepository { //implement the interface rules } class SocialUserRepository extends CoreUserRepository { //implement the specific logic related to a SocialUser } 

Update

As described in Mjh's comments, just implementing the interface on all UserTypeRepository caused a repetition - maybe not what you want!

By extending CoreUser , you avoid repetition and maintain a design that will work for your situation.

Although in your case it can be argued that you are still following SRP, because everything in the User model refers to the user, this is only the type of user that is different.

Why look for a storage template?

  • You warrant that you have a contractual agreement that must be followed by all User Repositories .

  • Code is easier to maintain.

  • Data and data access logic can be tested separately

Should the user model be expanded?

Here you are threatened by model pollution. Although you can do anything with the model - not everything is a good idea.

Defining relationships on this approach would be a headache due to confusion.

0
source

All Articles