I have a form with inputs that do not really belong inside any model. Things like "confirm password" and "I accept these conditions" etc.
What is the best practice for situations such as this?
I thought about the following possibilities:
Create a temporary model inside the controller action with validation rules.
Create a separate model for these inputs.
Some other feature in cake 2.x specifically for this situation?
I've read many answer posts about this but either the answer is for v1.x of cake and might be outdated, or people propose to put all that stuff inside the model with the closest relationship to the current controller. So what is the best practice?
Thanks!
I use behaviors for that.
Password add/edit:
https://github.com/dereuromark/tools/blob/master/src/Model/Behavior/PasswordableBehavior.php
( see https://www.dereuromark.de/2011/08/25/working-with-passwords-in-cakephp/ )
Accept Conditions:
https://github.com/dereuromark/tools/blob/master/src/Model/Behavior/ConfirmableBehavior.php
( see https://www.dereuromark.de/2011/07/05/introducing-two-cakephp-behaviors/ )
This allows me a DRY approach without having to repeat it all over again in the different models where I use them. I just add them dynamically ($this->Behaviors->load()) or via $actsAs and can use the extended functionality (similar to Traits in PHP5.4).
You could put your password validate stuff into the APP user model for a single app. But as soon as you are maintaining multiple apps the code would have to be duplicate at some point. That's why I prefer the behaviorable approach.
But it is neither impossible nor impractible for some situations to just drop the validation in the respective models.
Just don't create temporary models or something. That usually is the wrong way to go.
Related
I have doubts whether every view should have its own ViewModel or should I pass the plain model where there is no need for ViewModel? (What concerns me is that if I start to mix these two concepts, then I will end up with jungle later on)
I tried to google it but no one talks about that, every post I run into just explains the purpose of ViewModel and I know that the main purpose of ViewModel is so you can pass multiple models to view.
It depends.
In many use cases the main purpose is not to expose fields to being bound on form submission that the user shouldn't be able to update. I wouldn't slavishly create them when not needed but it depends on the developers and their level of understanding on when and why you use viewmodels vs domain/ef models. Also application code base size makes a difference.
Maybe you need select lists, maybe you want to convert some properties to different types. Lots of reasons to use them. However it is more code and mapping code even if you use a tool like AutoMapper. So they cost time to implement but maybe they fix problems and save other time? Maybe they fix a security problem? Maybe doing them all the as view models helps juniors understand? Maybe you would rather do the setup of a viewmodel at start than convert code later when it is really needed?
Consistency can help but doing a bunch of extra work may not be worthwhile. Best practice for me isn't best practice for you.
Consider the costs and benefits for your project and team . E.g. maybe your project is internal and no one is going to try to hack via adding data to submission
There are couple of reason to choose ViewModel over DomainModel.
1) First thing first is the security. Imagin you have a view for changing the password. If you pass the domain model to the view. probably you are exposing a lot of properties which is not necessary and it may cause a security problem. There is no reason to expose properties like LastLoginDate, IsActive, IsEnabled, NumberOfFailedLogin and so on for just changing the password.
2) The second reason is reducing logic from the view. If you pass a Domain class to the view, Possibly you need to add some extra logic for hiding extra properties or shape it as you like or adding logic based on the route and etc.
3) Because of the architecture. Exposing domain model to the view cause tightly coupling between your presentation layer and domain model which is not good at all.
A topic about single action controllers is in the laravel documentation:
https://laravel.com/docs/5.5/controllers#single-action-controllers
My question is, what is the use case where you will use this controllers? How will you structure your controllers if you opt to use single action controllers for all your controllers?
Michale Dyrynda seems to sum up the pupose of Single Action Controllers in his blog: https://dyrynda.com.au/blog/single-action-controllers-in-laravel
Conclusion
Single action controllers are an effective way to wrap up simple functionality into clearly named classes.
They can be used in instances where you're not necessarily following a RESTful approach; be careful not to separate multiple actions for a single entity across multiple controllers.
Where you might have previously used a single controller for multiple static pages, you could consider separate named controllers for each static pages.
You can add other methods to this class, but they should be related to the single action this controller is responsible for.
He also states that, you should only use these when you only need a single action for an entity:
You may consider naming the controller ShowPost as a way of being explicit about the controller's intent but I'd suggest caution with this approach; if you start seeing ShowPost, EditPost, CreatePost, etc controllers creeping into your codebase, I'd reconsider the RESTful approach. More controllers never hurt anybody, but we should be smart about when this is done!
This is an intresting question and my answer is not related to laravel, but to the single vs multiple actions per controller.
I have found when trying to find the use case for a pattern that is new, is to ask the inverse questions, in this case, when is the use case of multiple actions per controller make sense?
The answer usualy comes to:
You have an object that has crud operations (because your using sql)
and its convenient to place all the stuff related to that object in
one spot.
This is akin to the answer of "I have a hammer, so everything is a screw" and IF your domain is as simple as a thin layer over a crud database, then that is the use case for multiple actions per controller.
What I have found is that any amount of complexity blows up the controllers, no matter how good your model is. The reason is CRUD opperations are apart of your model, not your controller.
We usually think that we will map nicely to a CRUD model in our controller, there are many front end frameworks that work amazing at that, untill....
Look at the most common aspect of applications, users. In the setup your going to have index of users, which I don't know who would look at that page besides admins, and they usualy want extra information. so for the index action, you need admin custom authentication.
Then creation, well, it does not make sense to have an user create an user, you need to ensure the user is not authentication.
Now we talk about reading. What data an admin, other users, current user, and anon user can see is massivily differnt, and will slowly build up in complexity.
Then delete, this is normally rare action, and on some models not needed, but you still put it up, because, well you have a hammer.
The update, do you put password updates in here too? what if the user forgot there password? do you put that in here? No, you make a new action called forgot password.
Well now you need update password action. What goes in the update is usually a gigantic mess of hell after a year.
Each pattern has its pros and cons, my general advice is to do multiple actions per controller when your system is trully CRUD OR you will not have to maintain the project for more than a year. If you have any amount of complexity that will have to maintained, avoid the model leaking into the controller and keep them seperate.
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
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.
What are the best practices for implementing models in the MVC pattern. Specifically, if I have "Users" do I need to implement 2 classes. One to manage all the users and one to manage a single user. So something like "Users" and "User"?
I'm writing a Zend Framework app in php but this is more a general question.
The model should be driven by the needs of the problem. So if you need to handle multiple users, then a class representing a collection of Users might be appropriate, yes. However, if you don't need it, don't write it! You may find that a simple array of User objects is sufficient for your purposes.
That's going to be application and MVC implementation specific. You might well define a class collecting logically related classes, or you could define a static register on the user class. This is more of an OO question than MVC.
I'll second Giraffe by saying the use of included collections is almost always better than trying to write your own.
But I think your original question could be reworded a little differently... "Do I need a separate class to manage users other than the User class?
I use a static factory class to build all of my users and save them back to the database again. I'm of the opinion that your model classes need to be as dumbed down as possible and that you use heavy controller classes to do all of the work to the model classes.