Plan and create database before baking any files? - cakephp

I'm really new to cakephp (3). I have a general question about baking models, views and controllers.
Do I have to completely plan and create the database scheme before baking any m., v. or c?
I'm afraid of overwriting my codes, when I extend my database-scheme. I'm thinking of a situation like this:
I have two tables "Articles" and "Users". I baked mvc-s, having a small but complete website. I tweaked the Users-Model/Entity for some validator-reasons (e.g.).
Now, two weeks later, I want to add a "Group" table, where one user can belong to many groups.
Normally, I could rebake the Users-mvc-files. But that would overwrite my whole website.
Do I make a mistake? Do I have to manually modify the mvc-files when extending tables?
What is the best practice for extending a cakephp-website?
Many thanks in advance.

You could just bake the MVC for the new table, Groups (should be plural), and then update the associations, if any, in other tables. For example, if Users belongs to Groups, after baking the Groups table, you could add:
// in /src/Model/Table/UsersTable.php
$this->belongsTo('Groups', [
'foreignKey' => 'group_id'
]);
Of course, this assumes you've added the 'group_id' field to the Users table in your database.
This is a fine solution if your table is small and your data model remains fairly static. But if you are working with many tables and you are still regularly making changes to the model, I would suggest doing what I did after blowing away all my controller changes a couple of times.
CakePHP 3 makes very cool use of Elements in it's Controller templates. You can copy the cakephp vendor templates into your src directory, and then provide your additional controller methods (like login()/logout() in UsersController) as elements. Then test for the model and include the appropriate elements for that model.
This way you can bake away and not worry about losing all your changes.

Yes, generally you have to plan for database scheme before baking your MVC.
You should manually do the changes if any alter/changes become in the table otherwise the bake will override all the codes you did.
All the very best

Related

Cakephp Is there a way make a Model that is based on another Model?

I'm trying to join two tables that are in two different databases. These databases don't necessarily have to be the same. So i'm trying to see if I can make a model off of one model and another model off the other model and join the two derived models. Or if there is a way that you know how to join two models of different databases that'd be great too.
It is not possible for a Model to use two Tables/Databases
A model is generally an access point to the database, and more specifically, to a certain table in the database. By default, each model uses the table who's name is plural of its own, i.e. a 'User' model uses the 'users' table.
Source
The second Answer says it is possible, but I don't think it will work the way you want it.
However it is possible for a Model to use a different Database.
You can then create a relationship to link them.
It could be achieved with useDbConfig easily (just tested).
Another way is to use DB view.

CakePHP model association based on field values?

I've got three tables (there's actually several more, but I only need the three for this problem). Applications, Appattrs and Appcats. In CakePHP parlance (as best as I can since I'm still learning the framenwork) Applications hasMany Appattrs and Appattrs belongsTo Applications. Easy.
The problem comes when I want to associate Appattrs and Appcat - the association is predicated on a field value and a corresponding foreign key in Appattrs. For instance:
If appattrs.type = 'appcatid' then appattrs.value would point to a record in the Appcat table.
The appattrs table holds static data appattrs.type='dateadded' and value='201201011300' as well as foreign key references. I'd rather not get into a discussion as to why data is stored this way, I just want to figure out how to create associations that will let me pull an application record, the associated attr records and then an attr record with its associated row from the appropriate table. Dynamically.
It seems to me that I should be able to create a model based on a query and then associate that model - I just can't seem to figure out how to do that.
--
If I need to post schema for the three tables, I can. I can also post my current model code, but honestly, right now it's just association variables so I don't think it'll get anyone anywhere.
Thow I do not understand the logic behind this design, I thing what you are looking for
is Creating and Destroying associations on the fly.
On this section of CakePHP Docs, it describes how you can associate models from within the corresponding controller.
So, for example, when you want to save specific data to Appattr model you can do some data checking and create your association using bind() method.
A very abstract approach to the above would be something like this
public function yourmethod() {
...
if ($this->request->data['Appattr']['type'] == 'sometype') {
$this->Appattr->bindModel(
array(/*Your association*/ => array(/* Your attributes...*/)
);
/* Rest of the logic follows */
}
}
This way you get your job done, but it's very possible to end up having very complicated
data in your database and thus having very complicated code.
I hope this helps

How do variable Model names work in CakePHP tables?

Looking at the tables (aros, acos) generated by the ACL component and for example the Favorites plugin by CakeDC I see the favorites table with the fields Favorite.user_id, Favorite.model and Favorite.foreign_key.
The last two combined are replacing the good old Favorite.post_id (presuming model has the value 'Post'). It is in a way a HABTM pivot table with a dynamic modelname on one side.
I can see the general and useful idea here but would like to know more about the application of it.
My question(s):
Does this pattern have a name?
How does this work code-wise? I can see the abstract principle, but what kind of model-code is needed to make this work? Does it involve a patchwork of queries, or does this allow for a smooth one-query implementention? E.g.: I'd like to fetch all marked-as-favorite Posts in the system and their related Users in one go.
And does this work both ways? (querying from both the Post model as well as the User model)
I'd like to work towards an abstraction where I put a behavior in place to take care of this pattern.
I did look into the CakeDC code but could not figure out the principle. It's a little too cryptic for my current knowledge. Hence my question here.
kind regards,
Bart
Does this pattern have a name?
http://en.wikipedia.org/wiki/Junction_table aka Join Table.
How does this work code-wise? I can see the abstract principle, but
what kind of model-code is needed to make this work? Does it involve a
patchwork of queries, or does this allow for a smooth one-query
implementention? E.g.: I'd like to fetch all marked-as-favorite Posts
in the system and their related Users in one go.
It is just a regular join table, that's all. You can simply rely on what CakePHP is building up when using the HABTM assocs or refine your query by using joins. See http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#joining-tables.
The model field is not needed in that "pattern" but allows you to have just one join table that can be used for many different tables/models. For example instead of having tags and users and posts associated by tags_posts and tags_users we simply use the same table and filter by the model field.
And does this work both ways? (querying from both the Post model as
well as the User model)
Yes if you set the HABTM association up in both models.
Thanks for using our plugins. ;)

Should models hold references to other models?

I am trying to build a WPF application using the MVVM pattern. It would be my first one.
In my database I have 2 tables a reports table and a columns table. Basically I just want to store the skeleton of reports by storing the name and some minor infos (header row...) and save all columns in the other table.
I am wondering what would be the best approach when creating my model:
should I do 2 models (Report and Column) for each table? And make an observable collection of Columns
Only 1 model and create a POCO Column with a regular list of Columns
If I go with the 2 models approach should I implement 2 modelViews or can I group everything in one modelview as I will work with only one report in the view (like the edit report view)?
Hope I was able to clearly explain my situation.
Just do each separately (i.e. one View/ViewModel/Model per table). You can refactor common items later (and/or as you're building).
ViewModels in MVVM usually have one-to-one relationship to View, unlike Asp.Net MVC. In order to decide how many Views/ViewModels you need you can start thinking of the interface. ViewModels is modeled UI, so if you have one screen in your app then you should start with one viewModel class, later you can refine it if it will be too big. Models are a little bit different, it depends how are you going to interact with them. I'm not sure what are you going to do with them, I had an experience of storing a report definition in database and it may happen that you do not really need two tables at all, you do not even need relational database, just save a blob with serialized XML. But anyway after deserializing it back to your object you will have at least two model classes - Column and Report, model is kind of lowest level of abstraction, if you won't have those two model classes you won't be able to distinguish these entities.

CakePHP hasAndBelogsToMany using save() vs. saveAll()

I am using a very intrinsic database with a CakePHP application and so far my multi-models views and controllers are working fine. I have a singular table (Entity) that have it's id on several other tables as the Foreign Key entity_id
Some tables are one to one relations (Like a Company is one Entity) and some are one to many (Entity can have several Addresses) and so on.
I won't/can't change the database model, so this is the structure.
I have been using saveAll() to save data on those tables with input names like:
Entity.type='x' (hidden inside the view)
Company.name
Address.0.street
Address.0.city
Address.1.street
Address.1.city
... and so on ...
and my save all is doing all the hard job, BEGIN TRANSACTION, all INSERTs and a final COMMIT ...
But now I've created a EntityCategory that is a n to n relation and created the full HABTM relation inside the model.
It works when I save() it but just the HABTM relation, and it saves everthing when I use saveAll() (just as before) except for the HABTM relation.
Am I missing something ? How I make this work correctly ? I am using the following code today:
if (!empty($this->data)) {
$this->Entity->saveAll($this->data);
$this->Entity->save($this->data);
}
The saveAll() saves all data in several tables, saves the id in Entity->id and the save() saves the HABTM relations, but I am not sure if it is correct or if it can bring me problems if I change some structure/model.
Is this the best way to use it? Is there a correct way to save that relations inside CakePHP ? What your experience/knowledge can tell me ?
This is fixed if you download the nightly.
Be careful though, something else might break.
The problem with saveAll() and HABTM associations is a known CakePHP issue, and has not been resolved as of 1.2 RC2.
As fas as best pratices for saving related model data goes, according to the CakePHP cookbook:
"When working with associated models, it is important to realize that saving model data should always be done by the corresponding CakePHP model. If you are saving a new Post and its associated Comments, then you would use both Post and Comment models during the save operation."
However, using saveAll() and save() should work, and IMHO is a more flexible/generic solution.

Resources