How do you guys plan out your MVC relationships?

boatBurner

shutup, crime!
Feb 24, 2012
1,522
35
0
Any tips for mapping out MVC relationships as well as one-to-ones and one-to-manys for complex apps?

I'm wondering if there are any resources to help visualize what you're trying to accomplish.

For the sake of not getting flamed, let's call it a learning tool.
 


From what you've said, it seems like you're most concerned about models, so I'll talk about that. If anyone wants to know about views and controllers, let me know.

I'm going to use the example of a blog.

First off, make a list of every object we'll have in a system.

Let's say we have:

User
Post
PostCategory
PostComment

Next, think of all the data (not relationships), and which model it belongs to. The simple way is to fill in the sentence "____ has ____", so maybe "User has password".

Let's say we end up with:

User
- Email address
- Signup date
- password (hashed)

Post
- Title
- Text

PostCategory
- Name

PostComment
- Comment

Next, we need to figure out relationships. You're usually going to have one-to-one, one-to-many, or many-to-many. To figure this out, pick two models, then ask yourself "How many of model 1 belongs to model 2" and "How many of model 2 belongs to model 1"?

For example, a User can have multiple Posts, but a Post can only have one User, therefore there is a one-to-many relationship.

Another example would be that a Post could belong in multiple Categories, and a Category could have mutiple Posts, so that would be a many-to-many relationship.

Relationships for our example:

User
- one-to-many with PostComment
- one-to-many with Post

Post
- one-to-many with PostComment
- many-to-many with PostCategory
- many-to-one with User

PostCategory
- many-to-many with Post

PostComment
- many-to-one with User
- many-to-one with PostCategory

You combine the data attributes and relationships into a model, the final missing piece is methods which operate on the model. For example, a simple method for Post would be count_comments(), which just returns how many comments a certain post has. Whatever calls these methods (most likely your controllers) should not have to care about the internal workings of the model, and so is resilient to changes (maybe you switch from an SQL database to MongoDB).

Obviously which framework / programming language you use affects the code that you'd produce for this example, but the principles should be the same for all.
 
^-- I do something almost identical to that after...

I first MindNode or do a quick hand (yes, really!) sketch of the "pages" on the site, and what is on them and how you get between them.

I use mindnode for both so I can see visually, and move things around drag-n-drop.
 
For databases, I always use mySQL's InnoDB engine, as it supports cascading of foreign keys, and database triggers, both of which are very helpful when keeping a clean database, plus also let me be a little more forgetful when writing the code, without jeopardizing quality.

For handling the requests, just a very standard MVC model. I have a .htaccess file in the root directory with:

Code:
RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ /index.php?route=$1 [L,QSA]

So every HTTP request where the file doesn't exist, gets sent to index.php?route=URI. It picks up the URI, parses as needed, and uses the first part as the main controller / handler. For example, going to domain.com/admin/ gets routed to the administration panel, domain.com/rest/ gets routed to the handler for the REST API, etc. If a controller / handler doesn't exist with the first segment of the URI, the request is handed off as the public web site.

Then two directories, /tpl/ for actual actual TPL / HTML templates, and /php/ for the PHP files that execute any needed code for the templates. For example, if going to domain.com/admin/user/create, it gets routed to the admin panel handler, auth is checked, then the file at /php/admin/user/create.php is executed, which displays the template at /tpl/admin/user/create.tpl.

Then for libraries / classes, I just use PHP's autoload() function. I have a /lib/ directory, so if you init say:

Code:
$user = new User();

If not already loaded, it will load the library at /lib/user.php. I don't know, but works well for me, and keeps everything nice and organized.
 
For databases, I always use mySQL's InnoDB engine, as it supports cascading of foreign keys, and database triggers, both of which are very helpful when keeping a clean database, plus also let me be a little more forgetful when writing the code, without jeopardizing quality.

For handling the requests, just a very standard MVC model. I have a .htaccess file in the root directory with:

Code:
RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ /index.php?route=$1 [L,QSA]

So every HTTP request where the file doesn't exist, gets sent to index.php?route=URI. It picks up the URI, parses as needed, and uses the first part as the main controller / handler. For example, going to domain.com/admin/ gets routed to the administration panel, domain.com/rest/ gets routed to the handler for the REST API, etc. If a controller / handler doesn't exist with the first segment of the URI, the request is handed off as the public web site.

Then two directories, /tpl/ for actual actual TPL / HTML templates, and /php/ for the PHP files that execute any needed code for the templates. For example, if going to domain.com/admin/user/create, it gets routed to the admin panel handler, auth is checked, then the file at /php/admin/user/create.php is executed, which displays the template at /tpl/admin/user/create.tpl.

Then for libraries / classes, I just use PHP's autoload() function. I have a /lib/ directory, so if you init say:

Code:
$user = new User();

If not already loaded, it will load the library at /lib/user.php. I don't know, but works well for me, and keeps everything nice and organized.

WTF, the question was about relationships wasn't it?