How to choose the test DB cakePHP testing - database

I am using the cake bake command to create my fixture and Test models. I have done it successfully with one of my models but i am having troubles with another one.
I dont know why, it tries to work with the default DB instead with the test one that i have already defined and that is the one used by the first model i tested.
Both Test models, the one which works well and this 2nd one which doesn't, have been created with cake bake and they look exactly the same.
Both of them have this in their fixture class:
public $import = array('records' => true, 'connection' => 'test');
Test defines the connection to my test database.
What can be the problem?
I have experiment something weird. In my test model if i use the singluar instead of the plural, it works with the default DB BUT if i change it to plural it works with the test DataBase. (but it can not call any method from the model, just defined methods such as find()).
For example:
public function setUp() {
parent::setUp();
//uses the default DB (i dont know why)
$this->Post = ClassRegistry::init('Post');
print_r($this->User->find('all'));
$this->Post->updatePostsStatus(1); //works well
//uses the default Test Database (i dont know why either)
$this->Post = ClassRegistry::init('Posts');
print_r($this->User->find('all'));
$this->Post->updatePostsStatus(1); //doesn't work. No function found.
/*SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'updatePostsStatus' at line 1*/
}
Thanks.
I HAVE UPDATED IT.
LAST UPDATE AND SOLUTION
The problem was the bad initialization of the Post Model constructor.
Using the plural was not relevant. It is like using any non existent model. It will always get the test database.
The answer for the good initialization of the constructor is here:
How to override model's constructor correctly in CakePHP

That sort of MySQL error can be very misleading in CakePHP.
Basically the actual problem is with the line $this->Post->updatePostsStatus(1); Specifically it's that eitherthe Post model or updatePostsStatus() method of the posts model doesn't exist.
You basically have a typo on this line, check the method name. Should it be updatePostStatus? (no plural on posts?)
For some reason, if you try to call an undefined method on a model in CakePHP, instead of reporting the method is not found, the "automagicness" of CakePHP kicks in and bizarrely it tries to push the unfound method name straight into MySQL.
Basically, because CakePHP cannot find the $this->Post->updatePostsStatus(1); method, it is actually trying to execute a MySQL query of updatePostsStatus ie mysql_query("updatePostsStatus');, which is why we are seeing this wierd database error. Chances are you've just misspelled the method name.
If the method name is still not the problem, it's something to do with the Posts model not being instantiated correctly. Although that seems doubtful as long as you got all the names right. It is definitely not a database issue, just Cakes lame way of handling unknown class methods automagically.

Related

Creating plugin for Django-CMS

I think I screwed up somewhere while trying to create a django-cms plugin and now I am unable to go back. The plugin (called sbbplugin) seems to be "working" (it gets displayed) but whenever I try to publish the site I get the following error:
DatabaseError at /admin/cms/page/18/publish/
relation "cmsplugin_sbbmodel" does not exist
LINE 1: ...id", "cmsplugin_sbbmodel"."cmsplugin_ptr_id" FROM "cmsplugin...
^
I tried removing the plugin but I can not do it because the page is not published. My plugin has no models or anything. Also I'm unable to remove the plugin from the page by clicking delete. Seems like the database is broken. Since I am not experienced enough to know what information you need I would appreciate it, if you could give me further instructions on what I should do.
Update: I think the problem is that I tried to use a model (sbbmodel) which I deleted. Should I try to add the model again? If so what should I do to fix the database? Do I have to run a migration for my app? Do I even have to register the plugin as an app?
Update2: So I tried to add the model again and migrate the app but I get the following error:
CommandError: One or more models did not validate:
sbbplugin.sbbmodel: Accessor for field 'cmsplugin_ptr' clashes with related field 'CMSPlugin.sbbmodel'. Add a related_name argument to the definition for 'cmsplugin_ptr'.
sbbplugin.sbbmodel: Reverse query name for field 'cmsplugin_ptr' clashes with related field 'CMSPlugin.sbbmodel'. Add a related_name argument to the definition for 'cmsplugin_ptr'.
S.sbbmodel: Accessor for field 'cmsplugin_ptr' clashes with related field 'CMSPlugin.sbbmodel'. Add a related_name argument to the definition for 'cmsplugin_ptr'.
S.sbbmodel: Reverse query name for field 'cmsplugin_ptr' clashes with related field 'CMSPlugin.sbbmodel'. Add a related_name argument to the definition for 'cmsplugin_ptr'.
which I do not really understand because I never specified a foreign key. I assume it is because I inherit from CMSPlugin. Any help?
I finally fixed it. First I removed every file that I created for my plugin. Then I deleted every instance of my plugin that was saved in the database. Unfortunately that did not solve the problem and I was still getting the same error even after restarting the server.
What did the trick was to go into phpPgAdmin and select all tables than choose "correct". It did not tell me what exactly the issue was but afterwards everything was back to normal again. So if you somehow run into the same problem, just "correct" your database automatically.

CakePHP doens't support load models?

I use CakePHP 1.3.9 but I can't use other Models in a Controller.
I use $this->loadModel('ModelName); and $this->ModelName->find('all') - always empty.
The variable $uses also doesn't work.
Why is it not working for me?
I used i18n and must set $locale...
Do you mean the data set is empty? If the model is not loaded, you shouldn't be able to call $this->ModelName->find() as $this->ModelName would be null. Does it throw an error? Your usage is correct, as stated in the manual : http://book.cakephp.org/view/992/loadModel
You can also do
App::import('Model', 'ModelName');
$model = new Model();
But I'm guessing that your current resultset is returning empty rather than the model itself not being set.
Have you tried looking at what $this->ModelName actually contains? Do the following and post it here
pr($this->ModelName)
It's considered bad practice to put (un-associated) models in your $uses array.
Depending what you are trying to do, you may be able to make use of containable behaviour.
$this->User->Post->find('all');
If not, you should be able to use loadModel:
$this->loadModel('Article');
$recentArticles = $this->Article->find('all', array('limit' => 5));
To quote Cake:
The loadModel function comes handy when you need to use a model which is not the controller's default model or its associated model.
JohnP and Ross are correct. Controller::loadModel() is clearly working and not your problem if pr($this->ModelName) is working for you.
As they mentioned, you're probably having trouble because the data simply isn't in the database. Or maybe there's something wrong with your query. Have you tried checking the query that's produced by CakePHP and trying to query the database directly through the MySQL command line (assuming you're using MySQL)?
Or is there any chance you've overloaded the Model::find() method?

ACL, AROs and ACOs, how to update them if there are new sections?

I'm trying to understand how use AROs and ACOs if I've added a section in my site.
The CakePHP guide is clear on how the concept of ACL works, but not on how it should be implemented in the code. Personally I've found all the part of the tutorial very unclear on how they should be used inside CakePHP framework. It seems to be most unfriendly part of CakePHP framework.
Now when I go in new sections I've created, I get this error, and I don't understand how I could fix it.
Warning (512): DbAcl::check() - Failed ARO/ACO node lookup in permissions check. Node references:
Aro: Array
(
[User] => Array (
[id] => 1
[username] => vittorio
[group_id] => 1
[created] => 2011-03-30 10:51:23
[modified] => 2011-03-30 10:51:23
[viewable] => 0
)
)
Aco: controllers/Works/index [CORE/cake/libs/controller/components/acl.php, line 273]
If I look on
http://book.cakephp.org/view/647/An-Automated-tool-for-creating-ACOs
and on
http://book.cakephp.org/view/996/Creating-Components#!/view/1548/Creating-ACOs-Access-Control-Objects
I should get the answers, but if I run this code calling the url mysite.com/build_acl again I only get these errors:
Missing Controller
Error: BuildAclController could not be found.
Error: Create the class BuildAclController below in file: app/controllers/build_acl_controller.php
<?php
class BuildAclController extends AppController {
var $name = 'BuildAcl';
}
?>
Notice: If you want to customize this error message, create app/views/errors/missing_controller.ctp
Does exist a decent guide who talks about ACL, AROs and ACOs and how to implement them on CakePHP without leave the reader lost?
Vittorio,
with due respect, ACL and AUTH combined are a very generic tool. Getting it to work for the first time annoyed me quite a bit. The main errors, which I keep seeing over and over again are:
Not calling build_acl after one or more new actions has been created.
Not initializing the newly arisen setup (fresh ACL nodes as output of
the previous step) with proper access
rights.
Not calling parent::beforeFilter() in every controller who inherits from parent app_controller (as often crucial settings reside in this method).
Trying to save a foobared setup instead of going over the Auth+Acl tutorial at the end of the book again. It works (no offense), many people accomplished it before, so you can, too (I do not say that it is accomplished instantaneously).
Reinventing the wheel: After a basic functioning Auth+Acl tutorial, check out the plugins on sourceforge and github.
Not reinventing the wheel ^^, afaik the perfect AUTH+ACL management plugin is yet to be written (but useable code does exist)
Good journey, Benjamin.
Edit0
Basic code hygiene helps, e.g. if you allow users as requesting objects and actions as controlled objects, it makes sense to write the build_acl() into the users_controller, directly followed by, e.g. init_db(), where you centralize settings access rights.
Do not forget to remove these hacks before going into production, even though setting correct access rights again would not hurt much, but imagine what john doe and friends do to your app if they run this function all the time Ü
mysite.com/build_acl
you must run build_acl in any action of your controller, you can't call it like that you're referring to an action without controller. at least you can try like this
mysite.com/{my_controller}/build_acl
or run it in app_controller's beforeFilter method e.g.
function beforeFilter(){
$this->build_acl();
}
of course the function itself must be declared in app_controller.

Cakephp call a function from another controller returns "Warning (512): SQL Error: 1064"

I'm sure this issue can be solved rapidly, but I don't find any answer on the web, so here I am. I want to call a function from another controller, but CakePHP does not recognize it as a function but as a query, returning a warning:
Warning (512): SQL Error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'goals' at line 1 [CORE/cake/libs/model/datasources/dbo_source.php, line 673]
Here's the logic of what I am trying to do:
//from the TeamController
$this->Team->Player->goals()
//in the PlayerController
function goals() {
//code
}
As you can guess by the names, a Team hasMany Players and a Player belongsTo a Team. I thought this was the way to deal with it, but it's obviously not working because the cake wants to launch an SQL query starting by "goals".
Cheers,
Nicolas.
Well, relationships are between models.So you cannot call a controller's function --- action, via them. That means if you want to make your code work fine ,goal() should be a function in player's model instead of in the controller.
BTW,calling a function from another controller is properly a bad idea.
Update:
to get the score of some player in team controller
/*in player's model*/
function goal($player_id)
{
return $the_score_of_player_id;
}
/*in team controller*/
$score = $this->Team->Player->goal($player_id);
Write the method goals() on the Player model (app/models/player.php). It is a data function as opposed to a data manipulation function and, therefore, is more properly located on the model.
None of the solutions here worked and it looked like the function had to be slightly different from the one on the other controller, so I decided to rewrite a new one in the controller.

Trouble changing databases for my models in codeigniter

I'm making a website with two different databases. Let's say one is DB1, and the other is DB2. I've set up my database.php in the config folder, so they each have the correct host/password/username/database etc with db['DB1']['hostname'] and the other db['DB2']['hostname'] etc, so I'm pretty sure I've got that part right.
According to CodeIgniter docs, I'm supposed to do $this->load->database('DB1') to get that one to work within my model. First, I put it in my constructor for my model, and it didn't work. Then I tried putting that line as the first line of every function in the model, and that didn't work. I'm still getting this error:
Error Number: 1146
Table 'DB2.stores' doesn't exist
When I'm trying to use DB1, and have done $this->load->database('DB1') as the first line of the model's function. Does anyone know what I'm doing wrong? Thanks!
There are a couple of caveats I ran into when I last tried to do that.
In your model constructor, load DB1 and DB2 as
$this->DB1=$this->load->database('DB1',true) //<-- notice the true parameter
$this->DB2=$this->load->database('DB2',true) //<-- notice the true parameter
and then use $this->DB1->get()->where()->result_array() etc.etc.
Caveat 2
make sure persistent connections are off... they are on by default in CI
$db['DB2']['pconnect'] = FALSE;
and
$db['DB2']['pconnect'] = FALSE;
in your application/config/database.php file
hope that helps...

Resources