I'm trying to use trackable behavior in CakePHP but with associated models.
I've taken TrackableBehavior as a Model Behavior from Croogo which is based upon a plugin from Jose Gonzalez.
It works like a charm, but I'm trying to find a way to make it work properly when the data of the child/associated model are returned in a view of the "parent" model.
The associations are:
Clients hasMany Notes
Notes belongTo Clients
To be more clear: Both Models use Trackable Behavior. In the Clients "view" view ( ugh ) I list all the notes that are owned by the Client. I'd like Trackable Behavior to return the trackable records ( created_by / modified_by ) for each note that is listed, yet it only returns the Trackable Array for the parent model ( Clients ).
Any ideas?
A bit embarrassing. It was as simple as adding this before using the find() method
$this->Model->recursive = 2;
so CakePHP would go a level deeper to fetch the associated data for each item.
Related
I have 3 models.
Webcast and Tag are associated witha HABTMA association.
Webcast and Host are associated with a hasMany relationship (Webcast has many Host).
When I do a Tag->find I get Tag and Webcast models, however I want to get all 3. How can I go about that?
If your query is using $this->webcast->find then you'll get everything your looking for, except you can't search 'TAG' without joining the tables before the query. If you want to search 'TAG' which I recommend in this situation then your need to go into your Tag model and create relationships there too.
Tag HABTM Webcast
should do it. If you're not getting host then try 'recursive' => 2 in your query.
$this->Tag->find('all');
OR
$this->Tag->find('all', array('recursive' => 2));
From docs
The recursive property defines how deep CakePHP should go to fetch associated model data via find(), and read() methods.
http://book.cakephp.org/2.0/en/models/model-attributes.html#recursive
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.
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
In my app, user can create vehicles. On the "show specific vehicle" page, I have an instance of Vehicle (which extend RelationalModel from Backbone Relational). When I change the avatar of the vehicle, this model is changed.
In another page "show vehicles list" of the application, I have a gallery showing the vehicles of the user. The models (instances of Vehicle too) are in a collection. Unfortunately, they have a different CID and thus are not updated properly when the user changes the avatar of the Vehicle in the show Page.
How to deal with that? I would like the Vehicle #9 to be the same everywhere.
I would define an application-level vehicleCollection (A) where you store all vehicles you get from every single request that returns vehicles (B, C). Since every vehicleId will be the same, you can do a look-up in the main collection (A) if the model already exists when you loop over the resultset from the other collection fetch (B, C).
You will most likely need to work with temporary collections and inject the relevant model from the main collection (A)
If you look through the tests that come with the Backbone package (or just go to their github repo) you can clearly see how it works adding the same model to different collections
I need a custom query pagination in CakePHP 1.2.
I have a reviews model and on one set of pages, it paginates the reviews model one way, and on another set of pages it does it another way with a different custom query. How do I overwrite paginate and paginateCount twice in the same model?
IMHO
I wouldn't do it in the same model.
I would have two different models with different overwrites depending on your requirements and use them in the paginate method accordingly.
Something like.
$this->paginate('Superreviews');
$this->paginate('Normalreviews');
Obviously in both model classes you would have:
var $name = 'Review';
HTH