newbie on cakePHP: modular approach
i am developing a groupon-like system, and i came into this project when the system is already around 70% built, and it was built using cakePHP, to be honest, i know nothing about cakePHP. and i came across this:
a member bought a deal
if(has_enough_account_balance){
if((parameters validated)){
insert into 'deal_user' table
log transaction
update 'deal' table by:
user_count = current user_count + bought deal //to determine whether this deal is tipped or not
if(this deal is tipped){
issue coupon
}
}
}else{
this_user_owed
}
the admin confirmed that a particular user has paid his/her owed deal payment
confirm has_paid
update into 'deal_user' table
log transaction
update 'deal' table by:
user_count = current user_count + bought deal //to determine whether this deal is tipped or not
if(this deal is tipped){
issue coupon
}
now seeing that the two of those has something in common, i am trying to do this:
a member bought a deal
if(has_enough_account_balance){
if((parameters validated)){
process_deal(parameters)
}
}else{
this_user_owed
}
on admin confirmation:
confirm has_paid
process_deal(parameters)
and process_deal would be:
function process_deal(parameters){
if(isset(deal_id)开发者_StackOverflow社区){
update into 'deal_user' table
}else{
insert into 'deal_user' table
}
log transaction
update 'deal' table by:
user_count = current user_count + bought deal //to determine whether this deal is tipped or not
if(this deal is tipped){
issue coupon
}
}
is it possible to do things like this ? and where is the best place should i put this process_deal method, i have tried to put this inside the app_controller class, but it seems that it wont update the table, i am not sure why can't it update (i am using the updateAll method), thank you very much
Looks like you can have this function implemented into /models/deal_user.php
or /models/deal.php
as model classes, so you can share the process_deal
across needy controllers.
When a controller need it, simply include the ModelClass. Fatter Models.
and furthermore, you should not include this function into your app_controller
as it might not make sense sharing this method across all other controllers, or instantiating the DealUser
and Deal
models across all controllers, and some might not need it at all.
If you tried debug($this)
inside a controller, you know how horrible the array is. The more Model
you include, the messier it will be.
Update
(Base on personal experience), put your code into following files when..
/app/bootstrap.php
- Is when you have shared codes among everywhere in your application, like
debug
,json_encode
(when PHP version < 5.2) etc
/app/controllers/components/*.php
- Is when you have shared code/logic among controllers, with very minimal DB interaction.
/app/models/*.php
- (Fat Models) Is when you have shared functionalities among a few controllers, that manipulate the data before saving into the DB, example such as your question above.
/app/libs/*.php
- Is when you have shared external codes that doesn't fit into MVC, like
TwitterOauth
, or other generic classes/packages, which does not make sense converting it into Components, or too complex to do so. Import them into cake by usingApp::import('Lib', <name>)
is pretty sufficient and neat.
/app/views/helpers/*.php
- Is when you have shared html codes to render, that required some logic before converting it from data into html codes.
/app/app_controller.php
- Is only when you need to do some hack on
beforeFilter
,beforeRender
etc, that need to have common functionalities among controllers. The reason is because, your*_controller
is extendingapp_controller
, and if you are tempted and then add sharedcomponents
,uses
,helpers
in theapp_controller
with the hope of having them in all controllers, it turns out that you have heavy controllers in every requests. Make it a habit try make yourapp_controller
as slim as possible. Write more codes in each controllers.
/app/app_model.php
- Same idea goes for
app_controller
/app/plugins/*/
- Is when you include external cake-like framework/features, or you can wrap certain framework into a plugin if you want.
/app/webroot/*/
- And never never put your code under webroot! It's not neat, break Cake's structure, and it's not recommended! It's evil. Considering moving your code out of Cake if they couldn't be fit into Cake.
I think that is all? Again, they are my personal experience base on coding experience. Do comment/edit if you think they are not correct.
I'd go with Lionel Chan's answer above.
Also, it would probably help you to read over the CakePHP documentation. What you're trying to do looks like it shouldn't be difficult, but you'll have much more luck if you learn the framework and work within it rather than trying to work around it just using what you already know.
Any code that deals with a certain model's database table should go in that particular model class (the fat models referred to by Lionel).
So you could put the process_deal
method in the Deal
model.
The DealsController
can then access the method like this:
$this->Deal->process_deal().
Then, if there's a relationship between two models, for example: DealUser hasMany Deal
, you can access the method from within an action in the DealUsersController
like this:
$this->DealUser->Deal->process_deal();
If there isn't a relationship between the models, you could still call the process_deal()
method from within an action in the DealUsersController
like this:
$this->loadModel('Deal');
$this->Deal->process_deal();
I hope this helps point you in the right direction, but I'd still recommend spending an hour or two perusing the CakePHP documentation linked to above because you're likely to find the answers to most of your questions there...
P.S. Kudos for going for the modular approach. It's always refreshing to see...
精彩评论