CakePHP error: cake bake is using the wrong table name - php

Using CakePHP 2.x
I have successfully generated many models, controllers, and views but one of them is just not working.
the database table is name 'server_cpu', The model appears to generate fine as I have compared it to other models that can be turned into controllers and views and it is identical. It also does have the useTable = 'server_cpu', but even still when I try to generate the Controller it tells me that the model has to have a table. After looking closely I believe that it is trying to use the table 'server_cpues', How can i force it to use 'server_cpu' and not 'server_cpues', note that I have tried emptying the /tmp/cache/ folder and that has no effect.
The error when attempting to generate a controller for 'ServerCpus' using cake bake: 'You must have a model for this class to build basic methods. Please try again.'

There are two possible solutions:
Firstly: simply changing the name of the table can resolve this problem, but it should be noted that for many this is not a possibly depending on the stage of development, for example if the current database is well established and used by many other systems or application this may not be possible. If you are starting from scratch this will be an easier solution.
Secondly: a slightly more complex solution would be to work with Inflectors to change the behavior of CakePHP. This can be done by modifying the file '/app/Config/bootstrap.php' to add a custom Inflector, for documentation on this refer to this for information on inflectors for CakePHP 2.x. For this particular situation you could use something like
Inflector::rules('plural', array('rules' => array( '/(.*)cpu$/i' => '\1Cpu' ) ));
Note the use of regex to recognize all string containing cpu

Related

Using codeigniter Models in another non-codeigniter project

I have 2 projects accessing the same DB. One is with CodeIgniter, the other is a home made mvc framework. I'd like to use the same Model layer.
Is it possible to access Codeigniter Models from another project?
I'm not exactly sure why you would want to be accessing the same DB from two different frameworks at the same time (sounds like a recipe for disaster), but in general, I would say, "no."
What you actually want is not the model itself, You actually want the active records class located in /system/database/DB_active_rec, as that's the most common usage.
That class extends CI_DB_driver
This class accepts the config parameter for the DB(connection information).
You then want to extract the drivers themselves being used for the specific database you're working, the drivers can found at /system/database/drivers.
CI->model simply loads the DB_active_rec, that's why you need to do $this->db->insert()
I've never did so myself, But I don't see any major dependencies in the files themselves. I might have missed something though

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)){
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 using App::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 extending app_controller, and if you are tempted and then add shared components, uses, helpers in the app_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 your app_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...

CakePHP, how it should be used to create this(inside) app?

What I have is the following db structure(tables):
lists[name,id]
list_items[title,list_id,content]
I've created the needed files and code(the MVC) needed to manage the first table(lists).
I also added the hasMany to the model class. At that point I am stuck.
What I need is a solution for managing each item (basic CRUD, I assume that complex management is just an advanced CRUD that I will find out how to do by myself).
I will be specific: since it's a content that have no place (but the admin) that it will be used by itself, should I -
create a full mvc structure for it? (can or should I implement it somehow[how?] in the lists package?
if not, how can I attach the tables? (since the use is about to be dropped in version 2)
would an element(cake concept/context) will be the appropriate way to create a view for such situation?
ANY insight will be appreciated.
If I undertant correctly, you want to create a CRUD part of this tables by yourself, without bake.
You need to write all the MVC estrucure and be carefull with the naming combention of cakephp http://cakebaker.42dh.com/2006/02/18/cakephp-conventions/
You need the model into app/models and also a a controller into app/controllers (remember naming combentions) and for each model you need a folder into /app/views.
Alfo, every, every function in your controller needs a view, even if this action doesn´t write anything to screen
I hope this was usefull.
Have you tried using Cake's bake feature? Your CRUD will be automatically created in about 2 seconds. I would also recommend you do the Blog tutorial to get a feel for scaffolding.
CakePHP is all about convention over configuration. Eg naming conventions for tables, controllers, models etc.. So much can be done automagically.

Scaffold is ignoring class file in CakePHP

when using scaffolding on a controller the views render fine and the app even attempts to insert the data; the problem is that the scaffold is completely ignoring the relations I'm defining in my model class, in fact it's ignoring the class entirely as I can delete the file and the controller still scaffolds and render the crud from the table.
Has this ever happened to you?
Edit to add:
Ok this just got weirder, I check my naming conventions and they are allright and to make things worse it's not only happening on scaffolding, I just created a simple table: id, name and country_id and it's ignoring my model file here too even without scaffolding.
Added more info for this question here: https://stackoverflow.com/questions/2945879/why-are-some-classes-created-on-the-fly-and-others-arent-in-cakephp-1-2-7
This probably means you have some sort of naming problem with your model and Cake is not using it to begin with, but makes up its own on the fly. Cake's automagic only works if you follow its naming conventions.
It's hard to say without more details though.
Sometimes, Cake caches too much for your own good. Try deleting the contents of the tmp/cache/ dir inside the cake dir structure and see if the errors keep appearing.

Common CRUD functions in PHP

Is there a simple way to write a common function for each of the CRUD (create, retreive, update, delete) operations in PHP WITHOUT using any framework. For example I wish to have a single create function that takes the table name and field names as parameters and inserts data into a mySQL database. Another requirement is that the function should be able to support joins I.e. it should be able to insert data into multiple tables if required.
I know that these tasks could be done by using a framework but because of various reasons - too lengthy to explain here - I cannot use them.
If you try to write such function you'll soon discover that you've just realized yet another framework.
Of course not, that's why those frameworks exist and implement crud facilities. I'd first try to convince whomever it takes to actually use an existing framework and second, failing the above, I'd take a look at one or two of them and copy the implementation ideas. Failing all that you could take a look at http://www.phpobjectgenerator.com/
Without any frameworks includes without any ORMs? Otherwise I would suggest to have a look at Doctrine or Propel.
I know the way you feel.
Pork.DbObject is a simple class that you can extend your objects from. It just needs a db connection class to work.
please check out:
www.schizofreend.nl/pork.dbobject/
(oh yeah, yuk # php object generator. bloat alert! who wants to have those custom functions in every class???)
I came across this question on SO a while back and I ended up not finding anything at that time that did this in a light-weight fashion.
I ended up writing my own and I recently got around to open sourcing it (MIT license) in case others may find it useful. It's up on Github, feel free to check it out and use it if it fits your needs!
https://github.com/ArthurD/php-crud-model-class
Hopefully it will find some use - would love to see some improvements / contributions, too so feel free to submit pull requests! :-)
I wrote this very thing, it's kind of a polished scaffold. It's basically a class the constructor of which takes the table to be used, an array containing field names and types, and an action. Based on this action the object calls a method on itself. For example:
This is the array I pass:
$data = array(array('name' => 'id', 'type' => 'hidden')
, array('name' => 'student', 'type' => 'text', 'title' => 'Student'));
Then I call the constructor:
new MyScaffold($table, 'edit', $data, $_GET['id']);
In the above case the constructor calls the 'edit' method which presents a form displaying data from the $table, but only fields I set up in my array. The record it uses is determined by the $_GET method. In this example the 'student' field is presented as a text-box (hence the 'text' type). The 'title' is simply the label used. Being 'hidden' the ID field is not shown for editing but is available to the program for use.
If I had passed 'delete' instead of 'edit' it would delete the record from the GET variable. If I passed only a table name it would default to a list of records with buttons for edit, delete, and new.
It's just one class that contains all the CRUD with lots of customisability. You can make it as complicated or as simple as you wish. By making it a generic class I can drop it in to any project and just pass instructions, table information and configuration information. I might for one table not want to permit new records from being added through the scaffold, in this case I might set "newbutton" to be false in my parameters array.
It's not a framework in the conventional sense. Just a standalone class that handles everything internally. There are some drawbacks to this. The key ones must be that all my tables must have a primary key called 'id', you could get away without this but it would complicate matters. Another being that a large array detailing information about each table to be managed must be prepared, but you need only do this once.
For a tutorial on this idea see here
I think you should write your own functions that achieve CRUD unless you are stressed for time. it might be a framework on it's own but you need to learn what the framework does before screaming framework....it also becomes handy to know these things because you can easily pickup bugs on the framework and fix them your self........
it is possible but I wouldn't recommend it.
If there's absolutely NO way to use a framework you could create a base class that all other model objects extend. You can then make the base class generate & execute SQL based on get_class() and get_class_vars().
Is it possible? Yes.
Would I recommend it? nope

Categories