Polymorphism table divided on 3 controllers - laravel

I am building an application where you can write reviews on a company their profile. This is normally a one to many relation, but in the application, you can also write reviews on an apartment page and arrangements page. So I have 3 different pages to add the review functionality. Obviously, the user can edit and delete reviews too.
the reviews table is polymorphic. So you have a field with reviewable_type and reviewable_id
Now I was thinking to make a ReviewController to reduce code duplication. The problem I am facing right now is that I need to display the reviews on these 3 different pages, but I don't want to include the same code in every controller (ApartmentController, ArrangementController, CompanyController).
What's the best way to achieve this solution without duplicating to much code.
I was thinking to put a special class outside the MVC pattern, but I want to keep is as close to the MVC pattern.
Also, I thought of putting another method in the 3 controllers, but then again there's going to be code duplication.

You can use the traits to achieve this.
Make a new trait ReviewTrait and put the code in it and use in all the controllers.
You can find more traits here Link.

Create a modal function inside the company modal lets called it Reviews, which takes the review type as a parameter.
Now call the modal function Reviews with review type in the ApartmentController, ArrangementController, CompanyController.

Related

How to handle conditional rendering of views related to same controller's action?

I am developing a simple CRMish application. Let's say I can create tasks and clients. Both can be created independently, but they can also be created in a process. I have a views called create.blade.php for these two actions.
When you are creating a task for example, at some point you have a button choose a customer / create a customer which opens a modal dialog (so you can pick a customer and assign it to a task in one step :)). And here it starts to get muddy. I want my form part from create.blade.php to be rendered in modal dialog and to do so I need to fetch this hitting my create action, which normally returns full form that extends master.blade.php.
How would you handle this kind of design problem? For now it would be a little, innocent switch or if before return view() in my create action but I know that it will look like spaghetti carbonara at some point.
My ideas are as follows:
ifs/switch as long as it's readable and it's only about returning
different views (but you know it will include logic, different
variables etc. at some point..)
move ifs/switch logic to some request class and call return
view($request->getView()) so my controller will be a little bit
cleaner and follow SRP
create different classes for "ajax" requests, and "normal" requests.
same as above but because the logic of fetching some data used in
form etc. are common for both of the scenarios I can create a base
abstract class of TaskController and than extend this for "normal"
request and "ajax" request scenario. This is most advanced idea, but
I think i follow SRP as well as I remove code duplication cause
fetching common data will be placed in abstract class
Do you have any other ideas of how to handle this?
I have ended up with a little conditional in my create.blade.php view.
#extends((( Request::ajax()) ? 'layouts.modal' : 'layouts.master' ))
According to #Kristo I wont overengineer, and stick with this simple & readable solution.
UPDATE
I have created a little extension, as I decided that I will not load my modals via Ajax but simply inject them on compile time. Here is the code :)
https://github.com/3amprogrammer/modal-blade-extension

In a MVC/MVP framework, how to deal with pages that are not associated with a single model / controller?

What we usually see in framework documentations are simple blog-like applications where each page is related to only one model and one controller.
How to deal with the most common case where a single page have to display information from different models?
Example:
A social network home page that shows:
Recent user posts
Recent users
News from the admins
Most played games
Is this supposed to be handled by a single controller that loads all this information from the different models and send it to a view that is potentially broken down into partials / elements?
Someone said in another question that I could create something like a HomePageController for pages like this. What if all that information should be displayed in the sidebar for all pages on the site, how do I handle that?
Typically, you'll collect all the different kinds of data and pass it to the view together:
MVC frameworks generally provide some way to map request URLs (e.g. /offers?id=5) to controllers (or their methods).
Let's assume that you want to display some data on your homepage.
To do this, you'll first define mapping from URL /home to some particular controller, let's say HomePageController.
Using your example data, you'll have something like this in your controller (in method that will handle request):
model.add(dao.getRecentUserPosts());
model.add(dao.getRecentUsers());
model.add(dao.getNewsFromAdmins());
model.add(dao.getMostPlayedGames());
render("viewName", model);
Upon request to some adress mapped to this specific controller, you will get different kinds of data from your Data Access Object (dao), and the add them to your model.
Once model is filled with data, you can pass it to a view ( = render view with this model), and in view you'll display it any way you want to.
I hope that basic flow is now clear to you.
Referring to #BeK's answer:
handling requests that take longer will always need an individual approach. You may choose to load this part asynchronously, you may (and probably will) try to cache as much as you can.
Loading the sidebar:
most of MVC frameworks provide some kind of 'base template' for your view.
That means you can define one part of view (e.g siderbar or footer) that is displayed on every page, and in particular controllers you only care about the dynamic parts. Those solutions are flexible enough to satisfy most of the typical needs.
There are a lot of options depending on what are you displaying in that sidebar - is it static or dynamic? what can be cached? etc.
There are several options here. It really depends on what kind of data you are loading. If one of the data requests takes a long time the view will not be displayed until all the data is gathered. If you break the view down in partials and let them load async, the user will have a better UX. In this way you can have the separate controllers/controller methods, complying with patterns like SRP.
If you want all the data to be displayed in the sidebar of every page, than maybe one controller taking care of it will be an easier solution, but again I would suggest take a look at the data you are loading and especially the time it takes to load all the data. Hope this answers your question or sets you on the right path.
alternate approach to follow SRP is using MVC child actions.
create many models and controller. each controller responsible for its own business logic
eg.
PostsController
NewsController
GamesController
HomeController
starting from HomeController that render the HomePage.cshtml
<div>#Html.Partial("Login.cshtml", Model.CurrentUser)</div>
<div>
<hgroup>
<h2>what's new</h2>
</hgroup>
<div>#Html.Action("WhatNew", "News")</div>
<div>#Html.Action("RecentlyPosted", "Posts")</div>
</div>
<aside>
<h2>Games</h2>
<div>#Html.Action("MostPlayed", "Games")</div>
</aside>
you may fetch list of many controller/actions name as string in HomeController then render multiple child actions in main page.

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

In MVC, how do you structure #Controllers with respect to Views, Models and Routing?

I have a question concerning the structure of an MVC application. Suppose we have to realize a web-based application composed by several modules, such as shopping cart, store browser(end-user), store manager(admin) and so on.
It is of course possible to create one controller and use the routing to submit the requests to a specific controller's action method. However this would make the code quite messy and hinder the practice to vertically structure the application, namely to identify and distinguish which views, models and controllers are involved to fulfill a specific requirement (an example is given by Phil Haack).
Another approach is to use one controller for each application section, for instance one controller made available for end-user operations, another for the store administrator, another one for queries made by the shipping department and so on. The drawback to this approach is to have too many controllers that mess up your code, too dedicated for specific tasks and so difficult to reuse.
According to this two extreme situation, what is the best way to organize your controllers and routing policies? Do you use a structured approach or it depends on the type of application you are developing?
Thanks
Francesco
It is of course possible to create one controller and use the routing to submit the requests to a specific controller's action method. [...]
Another approach is to use one controller for each application section, [...]
You're overlooking a third alternative, which is the most common one. In general you should have one controller per resource. A resource is a model that is publicly exposed. In your specific storefront application, the resources would be things like Products, Orders, Customers, etc.
This is typically the proper level of abstraction, because controllers usually don't need to know about models other than the resources they touch. A controller that touches more than one resource should be viewed with some skepticism, since it's violating the single-responsibility principle.
You should try to follow REST as much as possible
Basically - that means controller for each 'collection' (Your entity).
If Your controllers will be RESTful, other parts (routing, views) will fit themselves accordingly.

Resources