MVC good or bad practice - php

I am working on my first MVC application in PHP (CodeIgniter framework). Let's say I have 2 controllers: Cont1 and Cont2
Cont1 is associated with the MySQL table 'cont1' and Cont2 is associated with table 'cont2'
In my Cont2 model, every time I have to insert a new entry in my cont2 table I have to update a field in cont1 (they're relational tables).
Is it considered a bad practice if I execute a MySQL query in the model of Cont2 to update a table that is associated with the model of Cont1? Are there any good MVC approaches to this problem?

Controllers are not associated to tables, nor is your Model just the Database, nor is Code Igniter's definition of ActiveRecord correct. Apart from that it is okay to update whatever needs updating from within the Model.

I usually have one controller, a page controller, and another, an admin controller.
I then have a "news" library for example and that library calls functions from the "news" model.
The functions in here allow me to add news, delete it, edit it but it also allows me to pull news from the database and display it on the website.
So I can use that library in both my admin controller and page controller. So controllers aren't associated with actual database tables. My news model utilises several other libraries that upload images and data into other tables in the database and your method is as a result perfectly fine.

Related

Models in Laravel 5

I'm doing a web app here using Laravel + AngularJS and I have a question.Do I need a model for each table that I have in my database? There are 87 tables in my database and I need to query all of them according to with the input that the User wants.
I just want to make sure with all tables must have a model file or if just one is enough.
There are 2 ways by which you can access your DB tables:
Eloquent ORM (dependent on Models)
DB Facade Query Builder(independent on Models)
Former, is more clean and best approach to perform DB query and related task, whereas latter is not clean, and it is going to be difficult for you to manage large application, as you told there are 80+ tables in your application.
Also, if you're using Eloquent way, then it's also a better to have a base model, which will have common code which you can inherit in child models. Like if you want to store "user id" who did some DB changes, then in the boot function, you can write Auth::id() and assign that value to changed_by field on your table.
In DB Facade way, you've to hard code table name every time you're performing DB operation, and which leads to inconsistency when you found that you've to change the name of the table, it's a rare scenario still it'll be difficult to manage if in a file there are multiple tables DB operation going on. There are options like, creating a global table name variable which can be accessed to perform DB operation.
Conclusion:
Yes, creating 80+ model for implementing Eloquent way is painful, but for a short term, as the application grows it will be easy for you to manage, it will be good for other developer if they start working on it, as it will give a overview of DB and it will improves code readability.
It depends on how you'd like to handle queries.
If you'd like to use Eloquent ORM, you need model classes to handle objects and relationships. That is a model for a table, except intermediate relationship tables, which may be accessed through pivot attribute.
Raw SQL queries are also supported. You don't really need model classes for them, as each result within the result array will be a PHP StdClass object. You need to write raw SQL though.
See Laravel documentation.

CakePHP: Queries in Controller or Models?

If I really go through the MVC approach, then the queries should be in the Model, in CakePHP case the Table Classes, but when I go through the tutorials and documentation that Cake Provides they simply state that queries should be in the Controller.
As you can see in the example over here on Cake's websites: https://book.cakephp.org/3.0/en/tutorials-and-examples/blog/part-two.html
But if I go through this link or many other I have come across, the query part should be in the Models: https://www.toptal.com/cakephp/most-common-cakephp-mistakes#common-mistake-3-keeping-business-logic-in-controllers-instead-of-models
It is not just about what Cake displays in the examples or some developers opinion, but what should really be the genuine way to code in Cake when dealing with database queries. I have found almost 90% people doing query related tasks in Controllers only for Cake, as they quote "Cake mentions the same in their examples". But what about the MVC way, we create Table Classes just to mention the associations then? If Cake's own website does that, then somehow it means they have done it intentionally.
It's a good programming practice that to use your database queries in your Model because you can reuse these queries(In another controller) later by calling the method using the object of the model. However, you can also write your queries in your Controller.
For example:-
//Consider this code block is in Products Model
function totalActiveProduct(){
$totalProduct=$this->find('all', ['conditions'=>['is_active'=>'Y']]);
return $totalProduct;
}
If you want to get the total active product in any controller you can do this,
$this->Categories->Products->totalActiveProduct(); //Total procuct in category controller
$this->Products->totalActiveProduct(); //Total products in Product controller.
Actually, when you are writing the query in you controller, you have to use the object of your model(That means indirectly you are using your controller). You are thinking that you are writing this in your controller but actually, you are writing it in the model(Object of Model).
$this->Products->find('all');
Simply this means you are writing this in your model object(Where Products is the model object). Directly or indirectly you are doing your each and every database operation through the Model.

MVC - should a model interact with (an)other model(s)? Or the controller should do that?

Apologise if it sounds a dumb question, but if I never ask, I'll never learn. I have been recently working with the MVC implementing pattern, and I'm still learning stuff, so please be patient with me.
I've been recently working on a multi-languages website that uses a custom MVC framework for a client. In some places I'd need to display some information from more than one table, like an article (from the articles table), the name of the languages that this article is written in (from the languages table), the languages that this article is not yet written in (from the languages table also), and the author (from the authors table).
I have a model for the articles, a model for the languages, and a model for the authors, and each has its own controller.
If I only query articles tables only or the authors tables only, there is no issue, but the confusion comes when I want to display information from this different tables into a single view.
How I should do that?
Instantiate a language model object and an author model object in the article controller and call their related functions to get the data and then combine/merge their data with the data from the article model (all in the article controller as mentioned)?
Instantiate the language model and the author model in the article model and call their functions to get their data, then combine/merge the their data with the data from the article model itself?
Do a join or nested select in the article model to get the data from multiple tables, and not interact with any other model, even if that mean some queries will be repeated in more than on model?
Another approach?
What is the best way do that?
This can be done in several ways:
- Create a view (a virtual table of MySQL) which using join, nested select or whatever you want to achieve all necessary information and create a model on top of this view in MVC (this model can only retrieve info from the view not alter it, however)
- Use repository pattern. A repository wrap many models and you can implement business logic (which might be CRUD on multiple models/tables) here. The controller simply use the repository instead of model.
In summary the model, repository should wrapping all the business logic of its own never let the controller do these stuff.
Regards,

Why do I need a Application_Model_User and Application_Model_DbTable_User in Zend?

Is there any point in having both? I followed a Zend tutorial which told me to create a user model but can't I just model the user in the DB model class?
Thanks
It's part and parcel of the concept of "separation of concerns" http://en.wikipedia.org/wiki/Separation_of_concerns
Your model class takes care of business logic, validation, variable manipulation etc and your db model class should just handle dealing with the database, that way if you need to replace the db model it wont affect the main model as much, and if you replace the main model it wont affect the db model as long as the right parameters are passed into it.
Yes, you can model your user in Application_Model_DbTable_User (DbTable class) and it will work fine as long as all of the data you need is in that one table.
At some point you will likely start working with objects that should be represented in more then one table. This is when you will discover the need for a different way to do things.
A better simple example of where a mapper and domain object might matter:
The mp3 file.
At it simplest a single music file should probably be represented by at least 3 db tables:
album: a table representing the album the song comes from
artist: the artist that recorded the song
track: the information about the track itself
each artist can have multiple albums, each album will have one artist and will have multiple tracks, each track will belong to one album and one artist (different versions will be different tracks).
As you can see the database stucture of even a simple mp3 collection can become very complex very quickly. In most cases even a simple user record will spread across multiple tables depending upon how much and what kind of data is being persisted.
For some help in understanding how and why to implement mappers and models I found these resources very helpful.
Building a Domain Model, covers what a domain model is and how to build one in PHP.
Adding Mappers to a Domain Model, adds mapper function to the same domain model.
Survive the Deepend, A Zend Framework starter that focuses on models and testing.
The first two links are done in plain PHP but are still very helpful.

Yii framework Many to Many relationships

What is the method to save and update Many to Many relationship in Yii framework?
There is a better implementation as behavior.
http://www.yiiframework.com/forum/index.php?/topic/6905-please-test-my-ar-enhancement-automatically-sync-many-many-table-when-calling-save/
Unless you create a model for the table between the two main tables, your only option is to use DAO (Database Access Object) and specify SQLs with it.
Have a look at how blog demo accomplishes this task.
use MANY_MANY relationship type to setup many to many connection between Models (An associative table is needed to break a many-to-many relationship into one-to-many relationships)
And now you can use all relational functions of Active Records
Yii Framework - The Definitive Guide to Yii: Working with Databases-Relational Active Record
The following extension does what you want...
Yii Framework - Extension: cadvancedbehavior
An important thing to note: On each update, the extension clears all previous records and creates new ones. So I wouldn't use it when the intermediatry table contains extra data other than the foreign keys.
you could set that up in mysql level..by going to relational view under each table in phpmyadmin and provide necessary relational condition..and use MANY_MANY in the model class inside relations..
The question is too common.
Usually data components with MANY to MANY relationships appear sequentially and independently. So you just need to do one insert action after another.
If your relationship needs dependent update you should user SQL triggers on the DataBase level. That'll ensure integrity of data and give a quite good separation in business logic of the application.
CREATE TRIGGER some_trigger
AFTER UPDATE ON some_table
...
END IF;
A similar way is to incapsulate relational data in one logical model on PHP level (and e.g. manipulate with 2-3 AR models there) and emulate SQL triggers logic in it.

Categories