I’m on Yii for a while now and I’m working on a project for myself. I’m making a textbased rpg game in Yii and am kinda stuck with the MVC pattern. The project is just a complex one and I got the feeling that I’m doing it all wrong in terms of MVC
Let me explain my problem with an example:
Situation
A user has money in his pocket and can earn by smuggling some drugs or booze from one city to another. This is saved inside the model UsersData.
I have a table named SmugglingPrices (with the cities and their smuggling prices per type of drugs)
I have a table named SmugglingUsers (with the amount of units per drugtype per user)
I have a controller named SmugglingController with actionIndex.
The output of the page with the form in it, is like this:
+-----------+----------------+-----------+---------------+
| Drug name | price per unit | buy/sell | your units |
+-----------+----------------+-----------+---------------+
| Marihuana | $ 100 | *TEXTBOX* | 1 |
| Cocaine | $ 150 | *TEXTBOX* | 4 |
| XTC | $ 320 | *TEXTBOX* | 1 |
+-----------+----------------+-----------+---------------+
Maximum amount of drugs you can carry: 15
Money in pocket: $ 10,000
*BUY BUTTON* *SELL BUTTON*
The MVC obscurity
Where do I have to check if the user has enough money in his pocket to buy the selected drugs?
Where do I have to calculate the total costs of drugs?
Where do I have to add or remove the money to/from the pocket of the user when he just sold or bought some drugs?
This is just one problem, but I got more like these… It just feels like I do not understand MVC enough to make a game I know how to make simple website with MVC, but not complex ones like these. I have read many articles like http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices but that doesn’t make things clear.
Can someone help me with this situation? And are there some very good explaining mvc tutorials/articles/forum-topics? I can’t continue my project right now, I first need to get these things right
[*]I think you’d want to do this client-side (and/or as validation in the model) so you don’t have to submit the page
[*]I think you should do this before (1) on the client side as well, then in the controller when you’re ready to commit to the db
[*]This should be in the controller as well, and act on the Users models
[/list]
I’m still learning, but I always try to equate things to how they would work in the yii blog example (when talking in terms of MVC). Clicking BUY/SELL is similar to submitting a comment…you’ll check the input values first (make sure they aren’t trying to buy or sell too much). Once the input is validated, you can be confident that when you send the data to the controller (POST), the controller will take all of the inputs and save the affected models.
You should try to put this logic into the models (“thin controller - fat model”), because it’s business logic you talk about.
The remaining question then is: Which model? Here i usually try to achieve a “natural” feeling: If your models where real life “persons”, who would you ask for the different tasks? For example “User, can you afford these items here?”. If you can’t find the right “person”, maybe you need to reconsider your model layout or introduce another model.
Some quick ideas about your case, which i didn’t think through in detail: Maybe you could use a Basket model (could be a pure form model), where you could add items, and get totals? Then add a methods to your User model, maybe validatePurchase($basket) to check if your user can buy this, or purchase($basket) that performs the purchase… hop you get the idea.
In my head, the objects are always having (partially violent!) disputes about who’s responsible for which task (“Come on, i’m the UserIdentity. It’s not my job to redirect to anywhere, ok…?”). This helps me a lot - and maybe as a role player you also can easily follow this vivid approach.
Thanks for the input Mike. I think that’s a great analogy to use. I’ve started to re-engineer my code based on this single post, and have had some decent results. For me it was very easy to fall into the trap of putting more of the logic within the controller since it seemed to be where all of my models meet.