Point cakephp 3 model to a different table - cakephp

For database organisation purposes, I have added pretext for every table.
I would then name models in Cakephp without the pretext, for less writing when calling them.
In Cakephp 2 I would use public $useTable = 'dev_pictures'; to point "Picture" model to "dev_pictures" table, in Cakephp 3, this has no effect. How would i do it in Cakephp 3?

Why not simply reading the migration guide?
It's now Table::table(), the method is a getter and setter. Set the table name in your tables initialize() method.

CakePHP 3.0 doesn't support table_prefix and 3.1 doesn't seem to be addressing that. So, in the meantime I think the simplest solution is doing the following:
class Picture extends AppModel {
public $useTable = 'dev_pictures';
}
(Take in account that CakePHP 2.x prefix support was not really solid).

Related

cakephp 2.10 get data without model class

Cakephp 2.10 ?
$text = $this->PrivacyPolicy->find('all', array(
'fields' => array('id', 'title', 'description')
));
How PrivacyPolicy is becoming a model role as there is no Model class in the files or relation with the database ?
Magic and unicorn dust... otherwise known as naming conventions and auto-models.
If no concrete model class can be found, CakePHP will create an instance of the AppModel base class instead, which will lookup the database table based on the the model name that you've used. So in your case the AppModel instance will look up the data in privacy_policies (lowercased, underscored, plural variant of the model name).
Quote from the docs:
CakePHP will dynamically create a model object for you if it cannot find a corresponding file in /app/Model. This also means that if your model file isn’t named correctly (for instance, if it is named ingredient.php or Ingredients.php rather than Ingredient.php), CakePHP will use an instance of AppModel rather than your model file (which CakePHP assumes is missing). If you’re trying to use a method you’ve defined in your model, or a behavior attached to your model, and you’re getting SQL errors that are the name of the method you’re calling, it’s a sure sign that CakePHP can’t find your model and you need to check the file names, your application cache, or both.
https://book.cakephp.org/2/en/models.html#understanding-models

Howto extend a plugin model class in CakePHP with "clean" classnames?

I'm currently learning CakePHP. I use CakePHP 2.2.3. I have succesfully "installed" a user management plugin. This plugin has a model class "User" and uses table "users". Now, I'd like to extend this User model in order to e.g. relate my own models to it, e.g. Posts.
I managed to to this with the following code:
App::import('Model', 'Usermgmt.User');
class MyUser extends User {
var $hasMany = array('Post');
var $useTable = 'users';
}
This works.
However, I don't like the fact that I have to call my Model class something like "MyUser". It makes everything very ugly and, maybe - theoretically - sometime I want to install another plugin that uses classname "MyUser". Is it somehow possible to use "clean" class names and prevent possible name collisions in the future..?
No, that's not possible because CakePHP doesn't yet support namespaces. According to the roadmap support for namespaces is planned for CakePHP 3.

How does cakePHP naming convention work?

I'm relatively new to PHP. Started learning PHP, but then come across cakePHP, which is suppose to speed up development time.
After reading the documentation and blog tutorial I still don't understand the naming convention. I guess I won't know until I start to do some examples, but to get me started can someone please explain to me how cakePHP associate database tables to the controller/model layer?
The below code is an abstract from the tutorial. It is a controller method that passes the post id to the view layer. The database table is called "posts". $this->Post refers to the model class of Post, which correlates to the plural form of posts in the database.
public function view($id = null) {
$this->Post->id = $id;
$this->set('post', $this->Post->read());
}
OK I get that. Then, in the documentation it refers to the following correlation:
ReallyBigPerson and really_big_people
So it seems like the correlation actually follows the rule in English semantics. Does this mean that cakePHP has a list of singular and plural words hidden somewhere that it works from? For example can I use the below correlation without breaking the code?
This and these or Man and men or Foot and feet or Moose and moose or Goose and geese
Furthermore, if I have both singular and plural form of tables in my database, will it break the code, or will it just associate to the plural-formed table?
Just find it baffling... Why couldn't they just match the naming convention like for like with prefixes?
Inflector
CakePHP uses its Inflector class to determine the plurals of things.
Since the naming conventions dictate that model names are singular and tables names are pluralised, it uses the inflector to apply English semantics / rules to determine the plural.
If you need some help understanding the output of the Inflector, you can use the CakePHP inflector website.
Pluralisation Examples
Model name: Post
Table name: posts
Model name: User
Table name: users
Model name: Sheep
Table name: sheep
Model name: News
Table name: news
Model name: Radius
Table name: radii
Check the Inflector site to be sure.
Non-standard Table names
While CakePHP offers a standard rule set for naming and conventions, none of it is set in stone. If you want to change the name of the table used for a particular model, simply specify the table name in the model:
class Thing extends AppModel {
public $useTable = 'somethings';
}
Or, if you want a model that does not use a table:
class Post extends AppModel {
public $useTable = null;
}

Dynamically passing a model name to a CakePHP Plugin

I'm having trouble wording my problem, so it's been tough to search for an answer. Hopefully you'll know how to help.
I am creating a CakePHP 2.1 Plugin that will interact with a series of its own Models:
- Friend
- Group
- User
Friend and Group are models that are created specifically for the Plugin, and they function within the plugin normally. However, the User model is really just an alias for some other table in the parent app.
So, if "My Awesome Application" decides to use "My Awesome Plugin", it will have to have its own "users" table (though it may called something else). Let's say "My Awesome Application" has a Model called MyUser. "My Awesome Plugin" wants to dynamically tell its internal User model to $useTable = "my_users".
My question is, how do I pass that data to the Plugin? How do I configure "My Awesome Plugin" to understand that User should $useTable "my_users";
As I understand you would like a Model in a PlugIn to use a table that would typically belong to a Model in your Application - by the conventions. Have you tried statically setting:
public $useTable = "my_users";
in the plugin? All plugins usually get initialized when Cake starts up, so all configurations should be loaded then. Why do you need this - it does really restrict you a lot? Will the table being used by the Plugin model change runtime?
The Model class also has some goodies you may find useful:
$this->User->table;
holds the table name for the model - the table that is currently being used that is**.
Also you can set the source table for the Model (inside a Controller) with:
$this->User->setSource('table_name);
** I am not sure if this applies when you use Model::setSource(). It would be interesting to check out what $this->User->table; holds after a Model::setSource() call.
I've figured out a way to accomplish this, but it might not work in all scenarios for all people.
I created a Component in my Plugin, and then I call the Component in my Controller. I pass the name of the users Model through the Component. This way, I can get information about the users Model, and I can set it as the useTable to my Plugin for use in the Plugin.
Of course, this method restricts me to using the Component to utilize the Plugin, but that's probably for the best.
Here's an example of how I did it:
// in the AppController
public $components = array(
'MyPlugin.MyPluginComponent' => array('userModel'=>'UserModelName')
);
// in the Plugin's Component
class MyPluginComponent extends Component {
function initialize($controller) {
//get the base user model
$this->UserModel = ClassRegistry::init($this->settings['userModel']);
//set the useTable for our plugin's user model
$this->PluginUser = ClassRegistry::init('MyPlugin.PluginUser');
//set the useTable value for this model
$this->PleaseUser->setSource($this->UserModel->useTable);
}
That seems to work for me. Hope this helps someone else.

CakePHP newbie question: How to add non-database attribute to model?

I want to create a model that has SOME attributes that are not stored in a database. For example, I want to maintain an "age" field in the model, but I only store birthday information in the database (I can calculate "age" once the DOB info has been loaded). I tried adding a simple attribute to a model extension, but as far as I can tell, it's ignored by CakePHP. What's the proper way to go about accomplishing this?
I'm a CakePHP novice, so forgive me if I'm missing something obvious.
I'd do it using the afterFind callback method in the model.
It's been a while since I dealt with Cake, but why not just implement a getAge() method?
If you are using CakePHP 1.3, you could use the 'virtual field':
http://book.cakephp.org/view/1608/Virtual-fields
[Cookbook 3.7.10]
[edit] It also works in CakePHP 2.x:
http://book.cakephp.org/2.0/en/models/virtual-fields.html
The main advantage of this approach is that the virtual field is added in the model. That way, the MVC principles are respected.
example (MySQL):
var $virtualFields = array(
'age' => "YEAR(NOW()) - YourModelHere.dob"
);
There are two ways of doing it with cake.
Use virtual fields http://book.cakephp.org/2.0/en/models/virtual-fields.html
Use call back function afterFind() http://changelog.in/2012/07/alternative-to-cakephps-virtual-fields-which-is-far-less-restrictive/
Use the class Cache:
$parametrs = array('age'=>21, 'name'=>'aziz');
Cache::write('myOptions', $parameters);
Cache::read('myOptions');

Resources