How to refactor laravel application code effectively - laravel

I'm in a position to refactor my laravel 5.4 app codes due to some problems: Code complexity, lack of oo design experience etc.
I have read that controller codes should be as short as possible (it is claimed that they are glue code parts).
Q1: I have some library like codes. These library functions/classes should be in the related Model classes, or should I have extra classes which make use of Model classes?
Q2: If I don't need extra classes (so model classes are enough), should I call these business logics from blade files, or from controllers? (Business logics in controllers make them quite large and complex).
Example: In a controller function, I evaluate post dataset with a query. After that I need some business logic for each post like effectiveValueOfPost($post). Should I call it from controller and pass it to the related view, or call it from blade file.
Thank you.

I am going to start refactoring my whole Laravel application according to the latest standards today itself. Here is how an Ideal Laravel application should be structured or created.
Note: These are not the hard rules but it will be easier to maintain your Laravel applications for future updates if you structure it this way.
Controllers:
Controllers should have these methods to Create, Read, Update and Destroy a specific model. To make it simple, Let's say our model is Product:
index() - It will return the list of products.
create() - It will show a form to create a model. (If required)
store() - It will store product information coming from a create form.
show() - It will return a specific product.
edit() - It will show a form to edit any product.
update() - It will update any specific product.
destroy() - It will delete a specific product.
Routes: Routes will follow the same pattern for different models. Here are the routes that will call above given functions in the controller for a specific model, in this case, products.
/products - GET - ProductController#index
/products/create - GET - ProductController#create
/products - POST - ProductController#store
/products/{id} - GET - ProductController#show
/products/{id}/edit - GET - ProductController#edit
/products/{id} - PATCH - ProductController#update
/products/{id} - DELETE - ProductController#destroy
Models: Now, all everything that deals with the database (Queries, complex queries, relations) will be stored in your Model (app/Product.php, in this case). There are no specified functions that you can use in Model. So, you can put all your queries and processing data from queries will be stored as functions in Model.
Views: The most basic model will require create, edit, index and show views. Inside views directory, you can create different directories for different models. In this case, there will be a directory called products inside views directory and it would contain all the above-given views as well as extra views that it might need.
I have worked on some really complex applications in Laravel. And this is the structure I follow to avoid any kind of confusion while creating or updating the application code. I don't even have to remember a random name that I gave to some view because everything is properly structured and totally based on the name of the controller.
Some controllers don't require all those routes and functions, in that case, you can still follow this method without being confused.

Related

What's the controller in MVC pattern and why does it exist?

While working with Unity, I realized that separating Model and View would make my code more readable and straightforward. Constructing the whole model, all I had to do is just create some UI and bind it to Model.
But I still don't understand what 'Controller' is, and why does it exist. I don't think I had trouble when I directly bound View to Model, not through Controller.
So the question is if we can bind View to Model directly, why do we need Controller? What's the benefit of having Controller between Model and View?
At the highest level the Controller is the link between the View (displaying the UI/UX) and the Model (creating and managing your database and its tables).
True, it is possible to write code without any Controller usage but your Views will quickly get very cluttered and each file will be full of logic that is much more nicely stored somewhere else hint hint.
The Controller (and Model and some other places such as helpers) is thus the perfect place to sort out all the back-end code so that all you need to do is send a single field or object to your View to display.
An example is somewhat painful because by its nature the Controller is where you go to sort out your code as things get more complicated but this is a great article to get you on the right track! HTH
https://www.toptal.com/unity-unity3d/unity-with-mvc-how-to-level-up-your-game-development
I don't have years of experience, but in my understanding controllers provide a bridge across view and models. While view contain the pretty part and models contain useful parts the controller do the calls of functions passing values from database to view or inputs to model. That provide a way to avoid lots of injection like class A calling class B, calling class C, etc.
You can put rule business in controllers or in view, but thats not the expected in MVC architecture. The first important thing (for me) in software programming is readability, whats MVC provide.
if you've interest, search for other architectures like MVVM, to compare then.

Sails.js - Multiple Controller/models in one page

I'm new to MVC pattern and Sails. From my understanding, it seems like I should create a controller for each model. A controller is like one page.
So, if I want create a page containing product category, product list and user authentication, there are 3 models in my page. How should I structure the controllers?
You don't have create separate controllers for each model.
Controllers handle the request from the client and return views, JSON, etc.
You may be being influenced by how sails documentation explains things due to their blueprints.
Mvc does not require a 1 to 1 of controller to model. Your controller should take care of massing the data and rules needed to show your view or a group of different views. A controller may have a link to a group of your functionality e.g. user management where you handle registrations, login, forgotten credentials etc. This may require a few different models and not just your user model. It may also display a number of different views too.
Sails.js comes with blueprints enabled which means a user model will have create,update,find,findone etc against a user model. Infact sails doesnt need a controller in this instance but you could make one to over ride logic or add additional logic. There is however nothing stopping you calling a user.find method in the user controller as well as a pets.find. Just think of the controller as the conductor telling and calling everything to fire and bringing this information together to push into a view or number of views.

Codeigniter use more than one controller?

This is more of a non-code related question. I want your experience here and suggestion. I am designing this simple web application where I could just insert data, and then making sure the website will view that data based on categories.
In my controller, I have functions, each loading based on which category is selected from my main page.
Now I am wondering, is it better to create multiple controllers (like I used to have separate classes when using OO Php) for say CRUD operations, Listing the records, Search functionality, etc. Or just keep it all centralized in one controller (the current approach)? If multiple controllers, any recommendations?
You should have a controller for each separate functionality your websites provides.
For example:
controller for handling "regular" content (articles) (displaying articles, searching, rating, etc)
controller for handling user management (login, logout, registering, etc...)
controller for "static" pages like about, help, tos, etc...
And you should also handle all database operations in model classes, each for different entity (model for articles, model for users...)
I hope you got the point
Codeigniter uses an MVC structure, so you should actually use models for database operations, and separate them in a way that each model is used for a specific functionality.
If all the categories are handled the same way, you should add all the retrieving from db code in a single model, that way you simplify your code making it a lot easier to maintain.

Generating Navigation for different user types, MVC, PHP

I have this idea of generating an array of user-links that will depend on user-roles.
The user can be a student or an admin.
What I have in mind is use a foreach loop to generate a list of links that is only available for certain users.
My problem is, I created a helper class called Navigation, but I am so certain that I MUST NOT hard-code the links in there, instead I want that helper class to just read an object sent from somewhere, and then will return the desired navigation array to a page.
Follow up questions, where do you think should i keep the links that will only be available for students, for admins. Should i just keep them in a text-file?
or if it is possible to create a controller that passes an array of links, for example
a method in nav_controller class -> studentLinks(){} that will send an array of links to the helper class, the the helper class will then send it to the view..
Sorry if I'm quite crazy at explaining. Do you have any related resources?
From your description it seems that you are building some education-related system. It would make sense to create implementation in such way, that you can later expand the project. Seems reasonable to expect addition of "lectors" as a role later.
Then again .. I am not sure how extensive your knowledge about MVC design pattern is.
That said, in this situation I would consider two ways to solve this:
View requests current user's status from model layer and, based on the response, requests additional data. Then view uses either admin or user templates and creates the response.
You can either hardcode the specific navigation items in the templates, from which you build the response, or the lit of available navigation items can be a part of the additional information that you requested from model layer.
The downside for this method is, that every time you need, when you need to add another group, you will have to rewrite some (if not all) view classes.
Wrap the structures from model layer in a containment object (the basis of implementation available in this post), which would let you restrict, what data is returned.
When using this approach, the views aways request all the available information from model layer, but some of it will return null, in which case the template would not be applied. To implement this, the list of available navigation items would have to be provided by model layer.
P.S. As you might have noticed from this description, view is not a template and model is not a class.
It really depends on what you're already using and the scale of your project. If you're using a db - stick it there. If you're using xml/json/yaml/whatever - store it in a file with corresponding format. If you have neither - hardcode it. What I mean - avoid using multiple technologies to store data. Also, if the links won't be updated frequently and the users won't be able to customize them I'd hardcode them. There's no point in creating something very complex for the sake of dynamics if the app will be mostly static.
Note that this question doesn't quite fit in stackoverflow. programmers.stackexchange.com would probably be a better fit

MVC - Codeigniter

Where should intermediate code be placed? (something that ins't just storing/retrieving data from DB nor processing requests/views)
For example,
Say I have Listings and I create CRUD functions in the model. These Listings may require more complex tasks such as pausing and resuming, which may require some time calculations, error setting, etc. Should these be placed in the model or should I wrap a simple model in a library and use that as a middleman for the model?
At the moment I'm thinking of using Drivers/Libraries and keeping models rather simple, except for some dynamic SELECT filters. I'm getting a bit confused though, since I'm guessing I'd probably have to recheck variables, dependencies, etc in the model after doing it in the library, yes?
I'd most likely either squish everything together in the model and check once or separate and check twice?
The general rule of thumb is:
1) Perform all business logic in the models.
2) Perform actions like a traffic cop would in controllers. (directing users to new views based on results of activities.)
3) Perform only presentational logic in views.
Anything else that you would like to do that would be considered, "intermediary", could reside in a Library or Helper.
It should be noted though that if you write a Library, don't forget to get an instance of the current CI object in your class so that you have it to use with your internal class methods.
class Your_lib {
$CI =& get_instance();
...
}
Hope that helps.

Resources