Assigning field values before saving on different models - cakephp

I continue building my CakePHP application. Now I've created all the database schema in MySQL, run some "cake bake all" and I have lots of models, views and controllers, and I'm gonna personalize them.
In many of my models I have this fields:
company_id
created_by
modified_by
As you can understand, the first field is the id of the owner of the "row", created_by is the id of who created the row and modified_by the latest person who updated it.
I know I can create a beforeSave filter in the model and update all the data (I suppose that I can know if I'm creating or updating a row, isn't it?), but just now I have 15 different models and I hope the app will grow more, so it's a lot of repetitive code to write. And, it breaks the DRY principle.
And my question is: Is there any "elegant" way to solve this problem? Maybe creating a class extending AppModel with a beforeSave filter for updating the fields, and that all my models inherit from the new Model class instead of AppModel?
Thanks for your help!

Make it a behaviour and load it for models that need that functionality.
See http://book.cakephp.org/2.0/en/models/behaviors.html#creating-behaviors

I think the most appropriate way is to create Behaviors.
You can set up the beforeSave callback in the behavior like what you have in your model.
Here is the link to the documentation http://book.cakephp.org/2.0/en/models/behaviors.html#behavior-callbacks

You can also check as example dereuromark's WhoDidItBehavior.

Related

Add content of form to 2 different tables cakephp

I am building a form with Cakephp 2.x and I want to submit some of the data that is received when submitting it to table A and the other data to table B. Does anyone know how to achieve this in cakephp?
I believe you need to look at Cakephp's model documentation. Looking at it now it seems that saveMany could help you with that. http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savemany-array-data-null-array-options-array
Yes. You should do what you want follow below way:
1. Create method receiveData() in FooController.
2. Create view file receive_data.ctp in folder foo.
$this->Foo->create();
$this->Foo->input('....', array(....));
// other input.
$this->Foo->end();
3. In FooController\receiveData(), When submit, you have data array $myDataArray like this: http://book.cakephp.org/2.0/en/tutorials-and-examples/blog/part-two.html#adding-posts
(Notice: It is Foo controller).
4. Before you save data from submitted data, you maybe need manipulation with submitted data array.
5.
You must call Model Bar inside FooController by:
$uses = array('Bar');
You will save to other table by:
$this->Bar->save($myDataArray);
(Notice: It is Bar Model).
Do Table A and Table B represent two different Models?
if yes saveAssociated might help you.
http://book.cakephp.org/2.0/en/models/saving-your-data.html#saving-related-model-data-hasone-hasmany-belongsto
If you want to save the same kind of model n times then saveMany is what you want to do.

Why isn't my ExtJS Store Association Working

I'm having issues. I want to use the nice ExtJS associations, but they're not working properly.
Issues:
no association showing in the model
no data showing up after load
What are the quirks to watch out for?
I recently went through a very painful learning curve with the ExtJS associations, and came across some useful articles, as well as my own gotchas. Here is the summary for those who run into the same pains.
Rules for HasMany Associations in ExtJS
Always put your Proxies in your Models, not your Stores, unless you
have a very good reason not to [1]
Always require your child models if
using them in hasMany relationships. [2]
Always use foreignKey if you want to load the children at will
Always use associationKey if you return the children in the same response as the parent
You can use both foreignKey and associationKey if you like
Always name your hasMany relationships
Always use fully qualified model names in your hasMany relationship
Consider giving the reader root a meaningful name (other than "data")
The child model does not need a belongsTo relationship for the hasMany to work
[1] The store will inherit its model's proxy, and you can always override it
[2] To make it easy, and avoid potential circular references, you can require them in app.js
http://extjs-tutorials.blogspot.com/2012/05/extjs-hasmany-relationships-rules.html
Rules for HasOne and BelongsTo Associations in ExtJS
Put the proxy in the model, unless you have a very good reason not to
Always use fully qualified model name
Always set the getterName
Always set the setterName
Always set the associationKey, if the foreign object is returned in the same response as this object
Always set the foreignKey, if you want to load the foreign object at will
Consider changing the instanceName to something shorter
The getter behaves differently depending on whether the foreign object is loaded
or not. If it's loaded, the foreign object is returned. Otherwise,
you need to pass in a callback to get it.
You should set the name property if you plan to override this association.
You do not need a belongsTo relationship for a hasMany to work
Set the primaryKey property if the id field of the parent model is not "id"
Sometimes you need to use uses or requires for the belongsTo association. Watch
out for circular references though.
Calling setter() function does
not seem to set the instance. Set object.belongsToInstance = obj if
calling the setter().
http://extjs-tutorials.blogspot.com/2012/05/extjs-belongsto-association-rules.html
Misc
If you're applying your data to a grid, make sure you call reconfigure() on the grid using the new store
Your "foreignKey" property will be applied as a local filter to the ExtJS store; if you see the data loading over the network, but
not showing in your grid, make sure your model has the foreignKey
value defined as a field, or the local filter will exclude the data
quiety. To test if this is the case, hook into the store's "load"
event and call store.clearFilters(), and see if your data shows up

Insert/save client search/form entries into separate table prior to running code- CakePHP

I want to store the form entries into a table that will store what my users searched for, then actually execute the code on the form results.
I tried doing:
$this->Search->create();
$this->Search->save($this->data);
But I don't think it liked me using a model that doesn't belong to that controller (my guess this doesn't follow convention and fully utilize CakePHP).
The other idea I had was to create a new searches_controller, then run $this->data through the above code and redirect back to the Trips controller but it seems like that's not the optimal way of doing it either.
Any thoughts on how best to do this?
In procedural PHP, I would just do an INSERT query before.
Thanks for the help!
I think that having Model which doesn't belong to the specific controller is not so bad idea.
Actually you can put this logic in the beforeFilter() of the Trips model like that:
class Trip extends AppModel {
//....
function beforeFind(){
if($this->data){
$search = ClassRegistry::init('Search'); //adding instance of Search model
$search->save($this->data); //save the data
//Do extra things if needed
}
}
//....
}
This way you don't have "alien" model in your controllers, and utilise the recommendation "Fat Models, Skinny controllers" :)

Can not Bake table model, controller and view

I developed small CakePHP application, and now I want to add one more table (in fact, model/controller/view) into system, named notes. I had already created a table of course.
But when I run command cake bake model, I do not get table Notes on the list. I can add it manually, but after that I get some errors when running cake bake controller and cake bake view.
Can you give me some clue why I have those problems, and how to add that new model?
I would also check your app/config/database.php to ensure that you are using the correct database configuration. You may well have added the table to a different database perhaps and the bake is picking up the other database. Also, and this may be obvious, but check you are in the right project, it's easy to be in a different folder and not realise, especially if you have lots of projects.
I'm not aware of a limit on the bake listing. I would check your database to make sure the table exists and has some columns. You can always open up the console bake script and check for a limit and increase it if needs be.
I found solution!
I had to delete all from cache directory, /app/tmp/cache/models
Now it works!
:-)
When you say added it manually, do you mean added the note.php model? If not, you may want to try that. Verify that the model name is correct for the following:
file name: note.php
class name: class Note extends AppModel
table name: notes
Also, be sure the notes table has the id column and it is set to primary key.
If this does not push you in the right direction, please post your notes table schema here. Also, have you had success in baking other things in your app? Have you upgraded anything?
Please change the following farameters to bake:
For Controller:
/cake/console/libs/tasks/controller.php
function listAll($useDbConfig = 'default') {
change to :
function listAll($useDbConfig = 'YOUR DB CONFIG NAME') {
NOW DO CAKE BAKE for CONTROLLER! ENJOY!

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