Laravel Repository pattern and many to many relation - laravel-5

In our new project we decided to use hexagonal architecture. We decided to use repository pattern to gain more data access abstraction. We are using command bus pattern as service layer.
In our dashboard page we need a lot of data and because of that we should use 3 level many to many relations (user -> projects -> skills -> review) and also skills should be active(status=1).
The problem rises here, where should i put this?
$userRepository->getDashboardData($userId).
2.$userRepository->getUser($userId)->withProjects()->withActiveSkills()->withReviews();
3.$user = $userRepository->getById();
$projects = $projectRepository->getByUserId($user->id);
$skills = $skillRepository->getActiveSkillsByProjectsIds($projectIds);
In this case, I couldn't find the benefits of repository pattern except coding to interface which can be achived with model interfac.
I think solution 3 is prefect but it adds a lot of work.

You have to decide (for example) from an object-oriented perspective if a "User" returned is one that has a collection of skills within it. If so, your returned user will already have those objects.
In the case of using regular objects, try to avoid child entities unless it makes good sense. Like, for example.. The 'User' entity is responsible for ensuring that the child entities play by the business rules. Prefer to use a different repository to select the other types of entities based on whatever other criteria.
Talking about a "relationship" in this way makes me feel like you're using ActiveRecord because otherwise they'd just be child objects. The "relationship" exists in the relational database. It only creeps into your objects if you're mixing database record / object like with AR.
In the case of using ActiveRecord objects, you might consider having specific methods on the repository to load the correctly configured member objects. $members->allIncludingSkills() or something perhaps. This is because you have to solve for N+1 when returning multiple entities. Then, you need to use eager-loading for the result set and you don't want to use the same eager loading configuration for every request.. Therefore, you need a way to delineate configurations per request.. One way to do this is to call different methods on the repository for different requests.
However, for me.. I'd prefer not to have a bunch of objects with just.. infinite reach.. For example.. You can have a $member->posts[0]->author->posts[0]->author->posts[0]->author->posts[0].
I prefer to keep things as 'flat' as possible.
$member = $members->withId($id);
$posts = $posts->writtenBy($member->id);
Or something like that. (just typing off the top of my head).
Nobody likes tons of nested arrays and ActiveRecord can be abused to the point where its objects are essentially arrays with methods and the potential for infinite nesting. So, while it can be a convenient way to work with data. I would work to prevent abusing relationships as a concept and keep your structures as flat as possible.
It's not only very possible to code without ORM 'relationship' functionality.. It's often easier.. You can tell that this functionality adds a ton of trouble because of just how many features the ORM has to provide in order to try to mitigate the pain.
And really, what's the point? It just keeps you from having to use the ID of a specific Member to do the lookup? Maybe it's easier to loop over a ton of different things I guess?
Repositories are really only particularly useful in the ActiveRecord case if you want to be able to test your code in isolation. Otherwise, you can create scopes and whatnot using Laravel's built-in functionality to prevent the need for redundant (and consequently brittle) query logic everywhere.
It's also perfectly reasonable to create models that exist SPECIFICALLY for the UI. You can have more than one ActiveRecord model that uses the same database table, for example, that you use just for a specific user-interface use-case. Dashboard for example. If you have a new use-case.. You just create a new model.
This, to me.. Is core to designing systems. Asking ourselves.. Ok, when we have a new use-case what will we have to do? If the answer is, sure our architecture is such that we just do this and this and we don't really have to mess with the rest.. then great! Otherwise, the answer is probably more like.. I have no idea.. I guess modify everything and hope it works.
There's many ways to approach this stuff. But, I would propose to avoid using a lot of complex tooling in exchange for simpler approaches / solutions. Repository is a great way to abstract away data persistence to allow for testing in isolation. If you want to test in isolation, use it. But, I'm not sure that I'm sold much on how ORM relationships work with an object model.
For example, do we have some massive Member object that contains the following?
All comments ever left by that member
All skills the member has
All recommendations that the member has made
All friend invites the member has sent
All friends that the member has established
I don't like the idea of these massive objects that are designed to just be containers for absolutely everything. I prefer to break objects into bits that are specifically designed for use-cases.
But, I'm rambling. In short..
Don't abuse ORM relationship functionality.
It's better to have multiple small objects that are specifically designed for a use-case than a few large ones that do everything.
Just my 2 cents.

Related

Should I save related models in repository?

I am working with Laravel for almost two years and trying to understand all the benefits of using Repositories and DDD. I still struggle with how to use best practices for working with data and models for better code reusability and nicer Architecture.
I have seen other developers suggesting to generate models in factories and then use Repositories for saving these models like :
public function add(User $user)
{
return $user->save();
}
but what should I do, in case my user model has models related with it, like images, description and settings.
Should I create repository for each model and call ->add() function 4 times in the controller or should I place the saving logic inside the UserRepository ->add() function passing all models as well as user? Also, how about update function, that logic might also be quite complicated.
Update - what I need is a practical example with realization.
It's always difficult to deal with "right way" questions. But here is one way.
From a DDD perspective, in this specific context, treat the User object as an aggregate root entity and the other objects as child value objects.
$description = new UserDescripton('Some description');
$image1 = new UserImage('head_shot','headshot.jpg');
$image2 = new UserImage('full_body','fullbody.jpg');
$user = new User('The Name',$description,[$image1,$image2]);
$userRepository->persist($user);
First thing to note is that you if really want to try and apply some of the ddd concepts then it is important to think in terms of domain models without worrying about how to persist them. If you find that you are basically writing a CRUD app with a bunch of getters and setters and almost no business logic then pretty much forget about it. All you will end up doing is to add complexity without much value.
The persist line is where the user will get stored. And you certainly don't want to have to write a bunch of code to store and update the children. Likewise, it would normally be waste of effort to make repositories for value objects. If you are going this route then you really need some sort of database layer that understands individual objects as well as their relations. It is the relations that are the key.
I assume you are using Laravel's Eloquent active record persistence layer. I'm not familiar enough with it to know how easy it is to persist and update an aggregate root.
The code I showed is actually based more on Doctrine 2 Object Relation Mapper and pretty much works out of the box. http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/ It is easy enough to integrate it with Laravel.
But even Doctrine 2 is largely CRUD oriented. In different domain contexts, the user object will be treated differently. It can start to get a bit involved to basically have different user implementations for different contexts. So make sure that the payoff in the domain layer is worth the effort.
I am not a PHP guy but from what I can find, Laravel an MVC framework, which has nothing to do with DDD.
Check this presentation, it does not to go to domain modelling, more concentrating on tactics but at least it has some goodness like command handling and domain events, briefly explains repositories with active record.
It also has references to two iconic DDD books at the last slide, I suggest you have a look at those too.

Streamlining the implementation of a Repository Pattern and SOA

I'm working with Laravel 5 but I think this question can be applied beyond the scope of a single framework or language. The last few days I've been all about writting interfaces and implementations for repositories, and then binding services to the IoC and all that stuff. It feels extremely slow.
If I need a new method in my service, say, Store::getReviews() I must create the relationship in my entity model class (data source, in this case Eloquent) then I must declare the method in the repo interface to make it required for any other implementation, then I must write the actual method in the repo implementation, then I have to create another method on the service that calls on the repo to extract all reviews for the store... (intentional run-on sentence) It feels like too much.
Creating a new model now isn't as simple as extending a base model class anymore. There are so many files I have to write and keep track of. Sometimes I'll get confused as of to where exactly I should put something, or find halfway throught setting up a method that I'm in the wrong class. I also lost Eloquent's query building in the service. Everytime I need something that Eloquent has, I have to implement it in the repo and the service.
The idea behind this architecture is awesome but the actual implementation I am finding extremely tedious. Is there a better, faster way to do things? I feel I'm beeing too messy, even though I put common methods and stuff in abstract classes. There's just too much to write.
I've wrestled with all this stuff as I moved to Laravel 5. That's when I decided to change my approach (it was tough decision). During this process I've come to the following conclusions:
I've decided to drop Eloquent (and the Active Record pattern). I don't even use the query builder. I do use the DB fascade still, as it's handy for things like parameterized query binding, transactions, logging, etc. Developers should know SQL, and if they are required to know it, then why force another layer of abstraction on them (a layer that cannot replace SQL fully or efficiently). And remember, the bridge from the OOP world to the Relational Database world is never going to be pretty. Bear with me, keeping reading...
Because of #1, I switched to Lumen where Eloquent is turned off by default. It's fast, lean, and still does everything I needed and loved in Laravel.
Each query fits in one of two categories (I suppose this is a form of CQRS):
3.1. Repositories (commands): These deal with changing state (writes) and situations where you need to hydrate an object and apply some rules before changing state (sometimes you have to do some reads to make a write) (also sometimes you do bulk writes and hydration may not be efficient, so just create repository methods that do this too). So I have a folder called "Domain" (for Domain Driven Design) and inside are more folders each representing how I think of my business domain. With each entity I have a paired repository. An entity here is a class that is like what others may call a "model", it holds properties and has methods that help me keep the properties valid or do work on them that will be eventually persisted in the repository. The repository is a class with a bunch of methods that represent all the types of querying I need to do that relates to that entity (ie. $repo->save()). The methods may accept a few parameters (to allow for a bit of dynamic query action inside, but not too much) and inside you'll find the raw queries and some code to hydrate the entities. You'll find that repositories typically accept and/or return entities.
3.2. Queries (a.k.a. screens?): I have a folder called "Queries" where I have different classes of methods that inside have raw queries to perform display work. The classes kind of just help for grouping together things but aren't the same as Repositories (ie. they don't do hydrating, writes, return entities, etc.). The goal is to use these for reads and most display purposes.
Don't interface so unnecessarily. Interfaces are good for polymorphic situations where you need them. Situations where you know you will be switching between multiple implementations. They are unneeded extra work when you are working 1:1. Plus, it's easy to take a class and turn it into an interface later. You never want to over optimize prematurely.
Because of #4, you don't need lots of service providers. I think it would be overkill to have a service provider for all my repositories.
If the almost mythological time comes when you want to switch out database engines, then all you have to do is go to two places. The two places mentioned in #3 above. You replace the raw queries inside. This is good, since you have a list of all the persistence methods your app needs. You can tailor each raw query inside those methods to work with the new data-store in the unique way that data-store calls for. The method stays the same but the internal querying gets changed. It is important to remember that the work needed to change out a database will obviously grow as your app grows but the complexity in your app has to go somewhere. Each raw query represents complexity. But you've encapsulated these raw queries, so you've done the best to shield the rest of your app!
I'm successfully using this approach inspired by DDD concepts. Once you are utilizing the repository approach then there is little need to use Eloquent IMHO. And I find I'm not writing extra stuff (as you mention in your question), all while still keeping my app flexible for future changes. Here is another approach from a fellow Artisan (although I don't necessarily agree with using Doctrine ORM). Good Luck and Happy Coding!
Laravel's Eloquent is an Active Record, this technology demands a lot of processing. Domain entities are understood as plain objects, for that purpose try to utilizes Doctrime ORM. I built a facilitator for use Lumen and doctrine ORM follow the link.
https://github.com/davists/Lumen-Doctrine-DDD-Generator
*for acurated perfomance analisys there is cachegrind.
http://kcachegrind.sourceforge.net/html/Home.html

What is the usage of Model in MVC? Is it actually useful?

I'm new in this, so bear with me. I've been using one MVC framework in a couple of projects lately, and after a while, I'm disillusioned in the perceived usefulness of the 'Model' in MVC.
I get the usefulness of Controllers and Views, I know that separation between presentation and logic is important to make the code more maintainable in the future, although not necessarily faster or more robust.
If all logic should be placed inside the controller in the first place, I don't see any use for Model, especially the Active-Record. We already have a language that is so robust and easy to use to communicate with the database, am I right? It's called SQL. For me when models are implemented like active-record, it's usefulness depends on whether or not you want your app to fit in multiple databases.
So what I'm asking is, if you're only using one database, why bother with Models and Active-Records? Why don't just use SQL? Why the extra layer of complexity? Do you guys have any case studies/real-life stories where models actually can do things better than just using the database class and SQL-away?
Again, I'm sorry if I seem to be so ignorant, but I really don't know why Models are important. Thanks for answering.
First, you are assuming that a model layer necessarily uses some kind of ORM, in order to abstract SQL away. This is not true: you may create a model layer which is loosely-coupled from the Controller layer but tightly-coupled to a particular DBMS, and so avoid using a full-featured ORM.
There are some ORM libraries, like Hibernate (Java), NHibernate (.NET), Doctrine (PHP) or ActiveRecord-Rails (Ruby) that really can generate all actual SQL statements for you; but if you think ORM is unnecessary, and you want to define all SQL statements by hand, don't use them.
Still, IMHO this does NOT mean you should just place all you DB related logic inside the controller layer. This is called the "fat controller" approach, and it is a road that leads, many times, to bloated, unmaintainable code. You could use it for simple CRUD projects, but anything beyond that will demand the existence of a real "Model".
You seem to care about MVC. Please, read also something about TDD. A wise man once said "legacy code is code without tests". When you learn that automated unit tests are as important as the "real" code, you will understand why there are so many layers in an enterprise application, and why your Model layer should be separate from the Controller. A block of code that tries to do everything (presentation, business logic, data persistence) simply cannot be easily tested (nor debugged by the way).
Edit
"Model" is a little bit fuzzy term. Depending from where you look at, it can mean something slightly different. For instance, PHP e Ruby programmers frequently use it as a synonym to an Active Record, which is not accurate. Some other developers seem to believe that a "model" is just some kind of DTO, which is also not right.
I rather use the definition of model as seen in Wikipedia:
The central component of MVC, the model, captures the application's behavior in terms of its problem domain, independent of the user interface. The model directly manages the application's data, logic and rules.
So the Model is the biggest, most important layer in most MVC applications. That's why it is usually divided in sub-layers: Domain, Service, Data Access and so on. The Model is usually exposed through the Domain, because it's there where you'll find the methods that your controller will call. But the Data Access layer belongs to the "Model" too. Anything that is related to data persistence and business logic belongs to it.
In most real-life situations, data that comes from the user doesn't go straight into the database.
It must often be validated, filtered, or transformed.
The role of the model layer is usually to make sure that data arrives properly into the backend store (usually the database) by performing these operations, which should not be the responsibility of the controller (skinny controller, fat model), and not the responsibility of the database engine itself.
In other words, the Model layer is responsible - or `knows' - how the data should be handled.
Most modern MVC frameworks provide ways to specify contracts over the data validity requirements, such as Rails.
Here's an example from http://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/:
class Cat
validates_inclusion_of :sex, :in => %w(M F), :message => 'must be M or F'
validates_inclusion_of :vaccinated, :in => [true,false]
validates_inclusion_of :fiv, :in => [true,false]
validates_inclusion_of :age, :within => 1..30
validates_each :weight do |record, attr, value|
record.errors.add attr, 'should be a minimum of 1 pound' if value and value /^[01][0-9]\/[0-9]{2}\/[0-9]{4}$/
validates_length_of :comment, :allow_blank => true, :allow_nil => true, :maximum => 500
end
Here, several of the data validity requirements cannot be handled by the database, and should not be handled in controllers, because any modification in those requirements might break the code in several places.
Therefore, the model is the best place to make sure data is coherent for your domain.
There's a lot more to be said about it, but I felt like tackling a point that seems important to me, motivated by practical experience :)
It's not an ignorant question at all! Just the fact that you're asking it instead of simply ignoring the whole MVC theory and doing as you please is nice. :-)
To answer your question: conceptually, Models simply provide a nice abstraction for your data. Instead of thinking in terms of "how do I write this inner join to get all the fields I need", models enable you to think in terms of "how are my application's objects related to each other, how do they interact and how can I get the data I need from them".
In the same way that Views and Controllers help you seperate presentation from logic, Models help you seperate the application's logic (from a user's perspective, anyway) from the gritty details as to where your data actually comes from and how it's represented internally.
To give a more specific example (if not completely realistic): in theory, you could write your whole application in a way you fetched all the data through SQL queries. But later you realized you wanted to use some noSQL (CouchDB, etc) engine because you needed horizontal scaling.
With models (and a framework that can use both types of storage, of course :-)) you wouldn't have to worry about the details, as all your important data is already represented in a generic manner through your models and both views and controllers can act upon that representation.
Without them, you'd probably have to rewrite a large chunk of code just to adapt your data fetching to the new backend.
And that's just on the boring storage part. With pure SQL, it's much harder to define the interactions between your application's objects (i.e. the business logic) because you just won't do that in SQL (probably, anyway).
It's not a perfect explanation (far from it), but I hope it helps.
The models should contain all your logic. The controller is only responsible with logic related to user interaction. All the domain-related functionality (what's known as "business logic") should be placed in the model and decoupled from controller code. Like this you can achieve a better separation of concerns and code reusability.
For example, let's say you are writing an application to let users enter information about themselfs and receive diet recomandations.
One the one hand, you would put code related to transforming user provided data into a list of diet recomandations in the model part. This includes database access, but also any calculations , algorithms and processing related to the problem in question (the problem domain).
On the other hand, you put the code to log the users in, show a form, gather the form data, validate it, in the controller. This way for instance you could later add an api to your app (which uses different code for authentication, getting data from the user, validation etc.) and reuse the code to generate the results (from the model).
This is just an example of what the model is good for.
I always relate Model to data irrespective of where it is present or how it is represented. In MVC V displays data and C handles change. Even if you have all the data to be presented on the screen in a HashMap inside your controller; that HashMap will be called the Model.

MVC Architecture. Whats in a model?

I am new to MVC but I can already see its benefits and advantages. However, I have a (probably easy to answer) design question:
I have been thinking about models and debating the proper way to structure them. The way I see it there are a few options:
1) Models and table structure have a 1 to 1 relationship...meaning that pretty much for every table there is a corresponding model. The model class has attributes corresponding to the table columns and has whatever methods that are needed (like getters and setters) to manipulate data in the table in whatever way is necessary. This seems like the generic option and I guess I would then have the controller call the models as necessary to perform whatever business function is necessary.
2) Models are tied more closely to the operation of the business logic rather than the data: so for example if on the front end a deletion of a certain object affects multiple tables, the model then 'models' this behavior and interacts with several tables and performs the necessary function. The controller then simply needs to call a single model for whatever business behavior is desired. This is less generic since the models are much more tightly coupled..but seems quicker to implement.
3) Something in between the first 2 options. Or maybe I am completely missing the point.
Hopefully this makes sense! If I am not totally missing the point, I am inclined to think that option (1) is better. Any idea?
Edit: Not that it should matter, but I plan on using Codeigniter PHP MVC framework.
Both are valid implementations, and, depending on your needs, can work well.
Your #1 is essentially describing the Active Record pattern, which is used by SubSonic, Castle, and lots of other ORM implementations.
Your #2 is essentially describing the Entity Framework/Hibernate/LightSpeed approach, where you are dealing with objects that are more conceptually related to your domain rather than to tables. Instead of your objects containing foreign key ID properties, they actually contain the other domain object references, which are then instantiated in an on-access basis.
Both ways are great. The Active Record approach is usually more intuitive for beginners and has potentially less pitfalls. EF-style can save a lot of base-level coding and dealing with FK's directly in code.
Edit: To be clear, what you describe in both situations is data access layer related, rather then strictly model related. However in reality you're pretty close, as most models tend to simply represent one or more of these types of objects.
All of the above.
The approach you use depends on your design philosophy. If you prefer to design your application using business domains and drive that into the database design, then you favor the second approach. If you prefer to build your database first, and then create model classes from the database schema, then you favor the first approach. Both methods are valid ways to build software.
Number 1 is the way to go. Option 2 is really the controller's job. For example, the controller then takes the models and performs actions on them, and passes the results to the view.
Think of it this way:
Model = your data
Controller = business logic
View = display of data and actions
This is highly simplistic, but it's how I picture it in my mind when I go to design a system.
Think of the database as the Model, the business logic as the Controller, and the UI as the View. That may help. It's an overly simplified approach to things, but it gets the data / behavior separation roughly correct.
I don't think it has to be an either/or situation. Your first point is what would be called a Model, but your 2nd point sounds like a View Model, which is most often a composition of various Models and parts of Models that will be sent to the view. The controller is responsible for doing that composition and potentially decomposition when information is sent back from the View.

Which one do you prefer for Searching/Reporting DataTable or DTO or Domain Class?

The project currently I am working in requires a lot of searhing/filtering pages. For example I have a comlex search page to get Issues by data,category,unit,...
Issue Domain Class is complex and contains lots of value objects and child objects.
.I am wondering how people deal with Searching/Filtering/Reporting for UI. As far As I know I have 3 options but none of them make me happier.
1.) Send parameters to Repository/DAO to Get DataTable and Bind DataTable to UI Controls.For Example to ASP.NET GridView
DataTable dataTable =issueReportRepository.FindBy(specs);
.....
grid.DataSource=dataTable;
grid.DataBind();
In this option I can simply by pass the Domain Layer and query database for given specs. And I dont have to get fully constructed complex Domain Object. No need for value objects,child objects,.. Get data to displayed in UI in DataTable directly from database and show in the UI.
But If have have to show a calculated field in UI like method return value I have to do this in the DataBase because I don't have fully domain object. I have to duplicate logic and DataTable problems like no intellisense etc...
2.)Send parameters to Repository/DAO to Get DTO and Bind DTO to UI Controls.
IList<IssueDTO> issueDTOs =issueReportRepository.FindBy(specs);
....
grid.DataSource=issueDTOs;
grid.DataBind();
In this option is same as like above but I have to create anemic DTO objects for every search page. Also For different Issue search pages I have to show different parts of the Issue Objects.IssueSearchDTO, CompanyIssueTO,MyIssueDTO....
3.) Send parameters to Real Repository class to get fully constructed Domain Objects.
IList<Issue> issues =issueRepository.FindBy(specs);
//Bind to grid...
I like Domain Driven Design and Patterns. There is no DTO or duplication logic in this option.but in this option I have to create lot's of child and value object that will not shown in the UI.Also it requires lot's ob join to get full domain object and performance cost for needles child objects and value objects.
I don't use any ORM tool Maybe I can implement Lazy Loading by hand for this version but It seems a bit overkill.
Which one do you prefer?Or Am I doing it wrong? Are there any suggestions or better way to do this?
I have a few suggestions, but of course the overall answer is "it depends".
First, you should be using an ORM tool or you should have a very good reason not to be doing so.
Second, implementing Lazy Loading by hand is relatively simple so in the event that you're not going to use an ORM tool, you can simply create properties on your objects that say something like:
private Foo _foo;
public Foo Foo
{
get {
if(_foo == null)
{
_foo = _repository.Get(id);
}
return _foo;
}
}
Third, performance is something that should be considered initially but should not drive you away from an elegant design. I would argue that you should use (3) initially and only deviate from it if its performance is insufficient. This results in writing the least amount of code and having the least duplication in your design.
If performance suffers you can address it easily in the UI layer using Caching and/or in your Domain layer using Lazy Loading. If these both fail to provide acceptable performance, then you can fall back to a DTO approach where you only pass back a lightweight collection of value objects needed.
This is a great question and I wanted to provide my answer as well. I think the technically best answer is to go with option #3. It provides the ability to best describe and organize the data along with scalability for future enhancements to reporting/searching requests.
However while this might be the overall best option, there is a huge cost IMO vs. the other (2) options which are the additional design time for all the classes and relationships needed to support the reporting needs (again under the premise that there is no ORM tool being used).
I struggle with this in a lot of my applications as well and the reality is that #2 is the best compromise between time and design. Now if you were asking about your busniess objects and all their needs there is no question that a fully laid out and properly designed model is important and there is no substitute. However when it comes to reporting and searching this to me is a different animal. #2 provides strongly typed data in the anemic classes and is not as primitive as hardcoded values in DataSets like #1, and still reduces greatly the amount of time needed to complete the design compared to #3.
Ideally I would love to extend my object model to encompass all reporting needs, but sometimes the effort required to do this is so extensive, that creating a separate set of classes just for reporting needs is an easier but still viable option. I actually asked almost this identical question a few years back and was also told that creating another set of classes (essentially DTOs) for reporting needs was not a bad option.
So to wrap it up, #3 is technically the best option, but #2 is probably the most realistic and viable option when considering time and quality together for complex reporting and searching needs.

Resources