Cakephp 3.0 bake error with foreign keys generated by Migrations - cakephp

I tried to bake my MVC in cakephp 3. I used Migrations to create my table including the foreign keys. Here's the code I use for migrations
{
$utTable = $this->table('unit_types');
$utTable
->addColumn('unit_type_desc','string')
->addColumn('created','datetime')
->addColumn('modified','datetime')
->create();
$mlTable = $this->table('master_lists');
$mlTable
->addColumn('unit_type_id','integer')
->addForeignKey('unit_type_id', 'unit_types', 'id')
->addColumn('created','datetime')
->addColumn('modified','datetime')
->create();
}
It prompts no error and seems to work well. but when I bake the master lists I got some errors, I saw '0 columns' phrase or something like that and a few more.
Now my question is, is this the proper way to put data association in cakephp? or should I be using my model files? I have no idea. I'm new to this framework. Thanks for any answers.

I don't know if you solve your problem, but I would suggest you to use save() instead of create().
For anyone searching the same topic, Cakephp 3 use the library Phinx to handle migrations, here is info about your problem: http://docs.phinx.org/en/latest/migrations.html#working-with-foreign-keys

Related

CakePHP 4.1 ORM many-to-many contain works one way but not the other

I'm facing an odd issue where a many-to-many relationship allows me to contain in one direction but not the other. I've managed to boil it down to a one-line example. In a controller,
this works as expected: $this->MarketplaceCategoryOptions->find()->contain(['Users'])->all()->toArray()
while this throws: $this->Users->find()->contain(['MarketplaceCategoryOptions'])->all()->toArray()
and the error is: Error: [RuntimeException] "_joinData" is missing from the belongsToMany results. Results cannot be created. in /application/vendor/cakephp/cakephp/src/ORM/Association/Loader/SelectWithPivotLoader.php on line 179.
Here are the models:
UsersTable.php
$this->belongsToMany('MarketplaceCategoryOptions')
->setThrough(MarketplaceCategoryOptionsUsersTable::class)
->setClassName('MarketplaceCategoryOptions')
->setForeignKey('user_id')
->setTargetForeignKey('marketplace_category_option_id');
and on the other side:
MarketplaceCategoryOptionsTable.php
$this->belongsToMany('Users')
->setThrough(MarketplaceCategoryOptionsUsersTable::class)
->setClassName('Users')
->setForeignKey('marketplace_category_option_id')
->setTargetForeignKey('user_id');
The join table:
MarketplaceCategoryOptionsUsersTable.php
$this->belongsTo('MarketplaceCategoryOptions')
->setForeignKey('marketplace_category_option_id')
->setJoinType('INNER');
$this->belongsTo('Users')
->setForeignKey('user_id')
->setJoinType('INNER');
The setup appears fully symmetrical to me so I really don't understand how it's possible for these two to behave differently. As far as I'm aware I'm following all cake conventions. I also have a bunch of other many-to-many associations just like this one in the same codebase and they work fine. I've also manually removed all cache from the tmp directory, just in case. Any ideas what could be the reason?

Scout create Table page out of database table

I heard that scout eclipse can create table page - AbstractPageWithTable out of database table properties, without manually adding columns for it.
Is this true, and if it is is somebody knows how to do it?
Dynamic UI Components:
I am not sure I understand your question correctly. Can I rephrase it like this:
How can I add a column dynamically (without having to define them as inner class)?
Here some pointers on the Scout Forum:
Is possible to create a dynamic PageView and Form ?
How to create UI fields at runtime?
...
My personal opinion is that the scout philosophy is to have a declarative UI defined with inner classes. I am not sure I would recommend someone to use this dynamic approach...
Scaffoling for Eclipse Scout:
From your comment, I now understand your question like this:
Given an existing database, is it possible to generate some elements of the application like TablePages?
I am afraid there is no open-source tool doing this for the moment. In our company, we have some developers, having a series of scripts to do something like what you are describing.
There is a project called SAML (Scout Application Modeling Language) where the user interface is described with a DSL and the Scout entities are generated. This is more a prototype that was built for the Kepler version of scout (3.9). For the moment there is no active development on it.
I have also started some builder where you do something like:
SimpleApplicationBuilder app = SimpleApplicationBuilder.create("myapp", "simple.myapp", "");
IScoutFormBuilder formBuilder = ScoutBuilders.form("MyFirstForm", "simple.myapp.client.ui.forms", "simple.myapp.shared.services")
.propTitle(app.nlsKey("MyFormTitle"))
.propSubTitle(app.nlsKey("MyFormSubTitle"))
.propAskIfNeedSave(false)
.propDisplayHint(DisplayHint.DISPLAY_HINT_VIEW)
.addField(ScoutBuilders.groupBox("ContentGroupBox")
.propBorderVisible(false)
.addField(ScoutBuilders.stringField("MyStringField")
.propLabel(app.nlsKey("MyStringLabel"))
)
.addField(ScoutBuilders.tableField("MyTableField")
.propTableStatusVisible(true)
.addTable(ScoutBuilders.table("MyTable")
.propAutoResizeColumns(true)
.addColumn(ScoutBuilders.integerColumn("IdComlum")
.propDisplayable(false)
)
.addColumn(ScoutBuilders.stringColumn("NameComlum")
.propHeaderText(app.nlsKey("Name"))
)
.addColumn(ScoutBuilders.integerColumn("AgeComlum")
.propHeaderText(app.nlsKey("Age"))
)
)
)
);
app.addForm(formBuilder);
The idea is to have a Java model of the application source code. It should allows to be able to do modifications or to add new entities and then to generate or modify the code. My tool is not open source for the moment (it is not finished yet and I do not have enough time to work on it).
I definitively think that scaffolding for Eclipse Scout would be great. I have published a master thesis proposal to work with a student on this topic. I hope we will be able to move forward.
Here some pointers in the Eclipse Scout forum:
Scout usage from command line
Form Generator based on DB Table layout
Let me know if you are interested in those topics.

Missing Model/Database Table in a Plugin in a CakePHP project

I have a CakePHP project having 3 plugins: Plugin1, Plugin2, Plugin3. These are simple plugins, I've just tried to split up my project into 3 smaller & easier parts.
Plugin1 has to use a model Model1, where there is no db table for this Model1.
I know the $useTable=false thing. My problem is, I have a function func() in that model, and I am trying to use that function func() in a Controller, in Plugin1. But it shows an SQL SYNTAX error. I think, usually we use the find() function of the model, but here we are creating a function and using, may be that's the problem.
Here, table-name and Model-name are in correct convention. I don't want to create a table for this, since I don't need it. What to do now ?

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.

How to choose the test DB cakePHP testing

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.

Resources