I've a question for CakePHP about its architecture.
I've an application, which will have only two models(products and categories).
I've to make an online product browser. For me it makes no sens to have one controller "Products" and one controller "Categories", because I will have 20+ actions on the Products and none on the Categories.
I've several key functionnalities, can I have one controller for each of those functionnalities? e.g. One Controller "Search", which have action "SearchResult", "AdvancedSearch", "BasicSearch".
We will be several developers on this project and I don't wish we are always all blocked because one is doing some edit on the product controller(and I really don't like file with 1000+ lines of code).
Second question: What is the mecanism I should use to fragment view in several different sub-view?
E.g. For the view of the details of one product, I've a lot of things to display: Pictures section, description section, similar products, review, ... Is it possible to have sub-part?
Thank you very much
For "sub-views" look into Elements, which are just that. They are snippets of view code that can be included in other views. The proper structuring of elements can create some very elegant view/subview relationships.
http://book.cakephp.org/view/1081/Elements
As for your controller issue, it's one I've grappled with as well. From what I see, it sounds like you're misclassifying your actions. Think about alternative taxonomies for the actions you're doing (mixing all the search functions together into a controller is a great example).
Perhaps you should think about controllers as objects that classify various actions rather than aspects of your site on which various actions can be performed (as it seems you're doing). So rather than a CATEGORY controller on which you can search, list, buy, etc., you might have, the product controller (which handles viewing your products either in an aggregate - perhaps by category - or individually), and perhaps a user controller for your users accounts? It's hard to say without looking at your application specifics. Search would then be an action that would be performed on your product.
One thing that I have made the mistake of doing is picking my controllers based on pages i'll have rather than on models. Think about your data (models) and the actions that can be performed on them (actions in the controller), THEN think about your views.
I wish I could give you more specific help, but without knowing your application's specific needs, I can only give you guidelines on how to break down your controllers. Take a look at this question:
CakePHP - file structure confusion - different controllers, or all in same?
for more discussion on the topic.
Hope that helps!
You don't need a Categories controller if you have no methods/actions associated with it. I assume you may want an admin CRUD for administrating your categories?
Regarding searching; your core search functions should reside in the Products model with the various controllers calling the appropriate methods. Basic or Advanced searching on one model in most cases can be handled by one method, its only a matter of more search fields surely?
If you have several developers and are worried about conflicts on the same file you really need to be considering version control like GIT or SVN rather than approaches contrary to a MVC frameworks core methodology. It will cause you a lot less problems in the future.
I believe you question regarding 'sub views' is solved by using elements, which is in effect reusable sections of views.
good luck
Related
I am working on this web platform where there are multiple tags associated with different objects like people, company, Articles.
I am following the RDBMS approach where i have:
A Tag model which is associated with all other above mentioned models through Many to Many fields. Things are working fine upto here.
Now, I want to create some kind of inter-relationship between tags so as to suggest related tags when user selects one tag the way quora or medium does when you are filling up your interests (not based on text).
One way would be to create a many to many field with self and then store the many to many objects whenever somebody selects two or more tags and then counting the instances when trying to figure out which tag are similar and predicting how closely two different tags can be associated.
What I am concerned about is that it could be too much taxing on the database.
Is there a better way to handle this. Please share thoughts.
I'm reaching out to gain perspective on possible solutions to this problem. I'll be using Angular and Rails, but really this problem is a bit more abstract and doesn't need to be answered in the context of these frameworks.
What are the best practices for managing complex nested SQL associations on the front-end?
Let's say you have posts and comments and comments are nested under posts. You send your posts to the front-end as JSON with comments nested under them. Now you can display them listed under each post, great. But then questions arise:
What if you want to display recent comments as well? Your comment service would need to have comments in a normalized collection or gain access to them in a fashion that allows them to be sorted by date.
Does this mean you make a separate API call for comments sorted by date? This would duplicate comments on the front-end and require you to update them in two places instead of one (one for the posts and one for the comment, assuming comments can be edited or updated).
Do you implement some kind of front-end data normalization? This meaning you have a caching layer that holds the nested data and then you distribute the individual resources to their corresponding service?
What if you have data that has varying levels of nesting? Continuing with the posts and comments example. What if your comments can be replied to up until a level of 10?
How does this effect your data model if you've made separate API calls for posts and comments?
How does this effect your caching layer if you choose that approach?
What if we're not just talking about posts? What if you can comment on photos and other resources?
How does this effect the two options for data-modeling patterns above?
Breaking from the example, what if we were talking about recursive relationships between friended users?
My initial thoughts and hypothetical solution
My initial thought and how I'd attack this is with a caching layer and normalize the data such that:
The caching layer handles any normalization necessary
The caching layer holds ONE canonical representation of each record
The services communicate with the caching layer to perform CRUD actions
The services generally don't care nor do they need to know how nested/complex the data model is, by the time the data reaches the services it is normalized
Recursive relationships would need to be finite at some point, you can't just continue nesting forever.
This all of course sounds great, but I see lots of potential pitfalls and wish to gain perspective. I'm finding it difficult to separate the abstract best practices from the concrete solutions to specific data models. I very interested to know how others have solved this problem and how they would go about solving it.
Thanks!
I assume you will use restful apis, attention I don't know rails but I will suggest you some general practices that you might consider
Let's say you have one page that shows 10 posts and their 10 comments sorted by date, make this response possible in one api call
There is one more page that shows only 5 posts and no comments use the same api end-point
Make this possible with some query parameters.
Try to optimize your response as much as you can.
You can have multiple response type in one end-point, in any programming languages, if we talking about APIs thats how I do the job.
If you query takes much time, and that query runs serveral times then of course you need to cache but talking about 10 posts in each api call doesn't need caching. It should not hard on database.
For nesting problem you can have a mechanism to make it possible i.e
I will fetch 10 posts and their all comments, I can send a query parameter that I want to include all comments of each post
like bar.com/api/v1/posts?include=comments
if I need only some customized data for their comments, I should be able to implement some custom include.
like bar.com/api/v1/posts?include=recent_comments
You API layer, should first match with your custom include if not found go on relation of the resources
for deeper references, like comments.publisher or recent_comments.publisher your API layer needs to know which resource are you currently working on it. You won't need this for normal include, but custom includes should describe that what model/resource they are point to that way it is possible to create endless chain
I don't know Rails, but you can make this pattern easily possible if you have a powerful ORM/ODM
Sometimes, you need to do some filtering same goes for this job too.
You can have filter query parameter and implement some custom filters
i.e
bar.com/api/v1/posts?include=recent_comments&filters=favorites
or forget about everything and make something below
bar.com/api/v1/posts?transformation=PageA
this will return 10 recent posts with their 10 recent comments
bar.com/api/v1/posts?transformation=PageB
this will return only 10 recent posts
bar.com/api/v1/posts?transformation=PageC
this will return 10 recent post and their all comments
I have been thinking about this lately. Up until now I have always subscribed to John Papa's recommendation which can be seen here:
https://github.com/johnpapa/angular-styleguide#controllers
Define a controller for a view, and try not to reuse the controller for other views. Instead, move reusable logic to factories and keep the controller simple and focused on its view.
He gives a reason that I don't understand but for me it was primarily motivated by ease-of-work/maintainability. Basically, in working on large applications, it really sucks to come upon a bloated controller that is responsible for several disparate views. If a developer wants to clean up the controller, he/she has to go to each view and determine what is being used and why (so that methods can be consolidated if they are very similar) which is a big job. Typically (especially if they are under time constraints), they choose to just add whatever functionality they need to the model and to "come back to it later" which is how it got bloated in the first place. Also, I have always used the controller/directive as an indication of whether logic is repeated in many views or not (i.e. if another developer walks up to a controller that I have written he/she can be sure that I have only used it with one view because otherwise it would be directive).
This is a similar problem to the endpoint-problem which basically has people adding endpoints on an as-need basis and the eventually due to new people not knowing about old endpoints or simple forgetfulness the API gets super bloated and repetitive.
However, as I said, recently I have been thinking that this 1-1 controller to view relationship really works against the entire MVC pattern because it couples the model to the view and destroys the separation of concerns. I mean, as long as a controller stays focused (i.e. we have an EditUserCtrl whose job it is to edit a user etc.) then why shouldn't two views be able to use that controller? I mean if the business decides it needs a new view in another place that has the same function, why shouldn't I just write a new view and hook it up to the old controller? I guess what I am saying is that I am having trouble reconciling a convention that goes against the fundamentals of a framework.
Would love to hear others thoughts on this. Thanks in advance.
Like you said yourself. If a controller is responsible for more than one view, any developer can walk up to it, change something in the hopes of adding new functionality to view A and not even knowing it's breaking view B. I think the primarily goal would be to keep controllers clean and neat. That way, it's best to have 2 controllers almost identicals, but with only 2~3 line of codes than to have files being referenced by a numerous number of other files that nobody has control over it.
At one hand, you have to change 2 controllers if something drastically changes in view A and view B, but if it's a complex task, you'll probably have the controllers calling some sort of Gateway and that might mean that you won't have to change any of the controllers at all (good outcome).
On the other hand, if you have 10 different views repeating the same 2~3 lines of code, maybe it's time to abstract the controller functionality.
It doesn't couple the model because the it's best practice to have the business logic in services and view logic in directives , and have there be no real logic in the controllers. So you can one controller per view, but that controller should be very skinny. Personally, I like to only use controllers to assign and communicate variables between services and directives. If you want to reuse controller code, what's stopping you from either putting that logic in directives and services?
Almost none of the controllers I write (and for my job I write a large enterprise application in angular) have logic in them. Granted sometimes logic in controllers is unavoidable, but try to keep as little as possible there.
In this way, the controller stays focused. For a large application, with, say, 10 pages, it's better for both usability and readability to have small controllers for each page instead of one giant controller with a mix of variables, and when you want to re-use methods and functions, put them in services. If you find yourself having three pages with a form or button that has the exact same logic, then that might be better served with a custom directive.
We're getting started on a new application that will run on several platforms (web, mobile, tablets etc). The goal is keep the models and controllers the same for all the platforms. Only the views will be changing. For example, if I have Roles view (and RolesCtrl) and Persons view (and PersonCtrl) on different pages (roles view redirects to persons page with role id as query string or something) on one platform, these two views might be combined into a single page (role id should not transfer to person page but to another view on the same page) on a different platform. I understand I can have separate divs and keeping the controllers intact, but since the UI flow is different for different platforms, how can that be handled? Is it feasible to keep the controllers unchanged?
Is this the right approach? Any help is greatly appreciated.
I would suggest proving this out by creating a small project to implement some piece of functionality backed by a service that AngularJS will communicate with.
It sounds like you might have some behind the scenes complications here. I would suggest that if you do use AngularJS to make sure all of the developers are making their HTTP communications done through AngularJS and not try to go work around it.
From my short experience with AngularJS I think it would work fine and may actually make things simpler because of it's easy single application model.
I am developing an application in cakePHP which has two sets of methods :
1) Methods which are called from the mobile phone to process payments
2) Methods which handle the website logic.
Now, the problem is that both the methods handling the mobile calls and the website logic are present in the same controller. This has made my code very difficult to manage.
Does anyone have any suggestions on how I can separate my code.
Thanks a lot
In the MVC architecture of CakePHP, each controller should be handling the transactions relating to one specific thing.
From the sounds of it, you should be separating your code into two controllers - one for payment, one for website logic
You could have more than one controller per model which would be the way I would go if there is no commonality across the two sub-applications, although if the number of models involved is significant this could result in many controller files.
On the other hand, if the number of methods is relatively limited, I would prefix the method names and group them together within one controller. I usually do this with ajax methods.
Most important is to be comfortable with whichever way you do it - you will probably be the one that maintains it!