2

I'm wondering if there's a best practice for this, I'm building a site that's going to require quite a few models and I don't want to end up with a unstructured mess. Basically I'm looking for a good rulesheet to structure out the models. Right now I can only think of two ways:

  • Every table in the db has its own model, ie. accounts.php, books.php etc.
  • A model represents a collection of methods, pertaining to a core module of the website, ie. a login model that contains methods like login, logout etc. a model that handles sessions, a model that handles cookies

Thanks for your time!

soren.qvist
  • 7,376
  • 14
  • 62
  • 91
  • 1
    Just as a side note, cookie handling isn't usually something done by the Model in MVC. That seems more like a helper class or method used by the controller, since setting cookies isn't really business logic. Generally, the Model should be the portable part of the application and should never communicate directly with the client. – Lotus Notes Jun 30 '10 at 21:56

5 Answers5

4

I suggest that model != table in general.

Instead, a model represents some component of your application's domain logic. This might correspond one-to-one to a database table sometimes, but it could also be that a model consists of several database tables, or no database tables. And some models could be comprised of a collection of other models. Also some tables may be used in multiple model classes.

The one-to-one relationship between models and tables is attractive for simplifying applications, but it's a type of coupling that can be misleading.

In MVC, the Controller and View are relatively easy and straightforward. They correspond to handling input and generating output. The Model is hard, because this is the rest of your application's data and logic. Welcome to OO design and architecture!

A good resource to learn how to architect models effectively is Domain-Driven Design by Eric Evans, or the free online short version, Domain-Driven Design Quickly.

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
  • Thanks, I think this is what I was looking for. The Model=Table approach is also a good source of headaches when you have cross-table relationships and don't use ORM. – soren.qvist Jun 30 '10 at 21:16
  • And don't forget http://domaindrivendesign.org/ and the [Sample App](http://dddsample.sourceforge.net/) - though I wish someone would port the examples to PHP. – Gordon Jun 30 '10 at 21:16
  • 2
    @Gordon: Thanks for the references! – Bill Karwin Jun 30 '10 at 21:29
2

This cannot be easily answered. Have a look at some of my answers to similar questions

for some ideas. But basically, all these mainly reference Patterns of Enterprise Application Architecture so you could just as well cut short to them.


I am marking this a Community Wiki, since it only references some answers. Feel free to vote on them instead of this answer.

Community
  • 1
  • 1
Gordon
  • 312,688
  • 75
  • 539
  • 559
1

The model per table is by far the most common way. And I think the cleanest as well. Your second method is going to end up as an unstructured mess.

But I think they both will end up being the same in the end. Because you'll probably only touch one table in the sessions model, and one in the login model, etc.

Timothy Baldridge
  • 10,455
  • 1
  • 44
  • 80
  • The web application would have to be almost impossibly simple to not even use a single relationship between two tables. – Lotus Notes Jun 30 '10 at 21:53
  • Agreed - even on a basic example of Users / Groups -> I would almost certainly somewhere in my application set up a user model that does "SELECT U.somevalue FROM `users` U, `groups` G where U.group_id = G.group_id – niggles Jul 01 '10 at 04:17
1

An ORM like Doctrine can help greatly in keeping things in order, but it does add overhead.

Just remember, the model should be the only part of your MVC structure that speaks with the database and contains the core business logic. As long as you stick to that rule, you are on the right track.

TomWilsonFL
  • 493
  • 2
  • 9
  • Thanks. I'm using CodeIgniter which isn't too happy about any of the most known ORM's out there. Otherwise, this would definetly my approach :) – soren.qvist Jun 30 '10 at 21:17
  • @soren: I actually have a large project going right now using CI + Doctrine. There is documentation on how to integrate them and it isn't that bad. This is old, but I believe it is what we followed with some minor tweaks: http://www.doctrine-project.org/blog/using-doctrine-with-codeigniter – TomWilsonFL Jul 01 '10 at 03:03
1

The only think that can cause a mess in your model folder is if your application is getting bigger and bigger and your framework does not allow you to structure the models in subfolders or you wasn't doing this.

Try out ORM. It has very strict rules, so you can't do much wrong in your structure.

antpaw
  • 15,444
  • 11
  • 59
  • 88
  • Thanks, TomWilsonFL answered this as well, my response: I'm using CodeIgniter which isn't too happy about any of the most known ORM's out there. Otherwise, this would definetly my approach – soren.qvist Jun 30 '10 at 21:19