Cake 2 data model for complex habtm relationship - saving and loading - cakephp

Abstract extra simplified example of issue:
DB structure is (simple version):
orders {
id,
name
}
items {
id,
name
}
items_orders {
order_id,
item_id,
quantity # problem item - many to many tables don't usually have this can't get cake to upport
}
So I have controllers and models for orders and items, they both habtm each other via the joinTable items_orders with the foreign keys specified, and I can load an order and all it's items, or an item and all the orders it is in, and save them, etc, however I can't figure out how to save/recover the quantity.
I am assuming I'll need to create an extra model to handle this, but can't find any documentation or similar posts here that explain how, or if there's an easy shortcut?

Using extra fields in join table is easy and explained in the cookbook.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasmany-through-the-join-model

Related

CakePHP: hasMany with join table

I have two models: Store and Review. Users of my site can leave a review on a store. In my database, I have a join table, reviews_stores that associates a review with a store.
How do I link my models? I assume a Store should haveMany Review, and a Review should belong to a Store, but the join table is causing issues with CakePHP as CakePHP is assuming my reviews table has a column called store_id.
The reason I'm using a join table is because many parts of my site can be reviewed. For example, brands. A new Review record will be created and a record will be inserted into a brands_reviews table to associate the two records.
Any help would be much appreciated.
Why are you not simply using one Review model and a reviews table with a field "foreign_key" and another field "model"? By this you do not need to duplicate tables and inherit or duplicate models. This will also remove the need for a join table.
If you want to continue to use your db design then you'll have to use a HABTM association over the hasMany association. But even in the case you want to keep that jointable, again, you can use the foreign_key/model and simply have one join table and one reviews table.
By the way, your join table review_store does not follow the conventions, it should be reviews_stores. But then it differs to the schema you've used for brands_reviews. ;)
Seems to me it isn't a many-many relationship but a grouped 1-many relationship. Id lose the join tables and simply have an extra table outlining which 'group' the review belongs to. So the review table would have review_id, link_id(the foreign key for the relevant brand or store), review_type_id(foreign key depicting whether the review is for a brand or store and so on). Then the review_type table only needs to have review_type_id, review_type(varchar).
There's no need for all the join tables for each model you can review, simple store the model name itself in a field in the Review table.
Setup your relationship like so:
class Store extends AppModel {
public $hasMany = array(
'Review' => array('conditions' => array('Review.model' => 'Store')
);
}
You can then do this with as many extra models as you like without having to touch the database.

Looking up column in related model

I have 3 tables. Here are they with their columns:
Result : id, title
Prospect: id, result_id, customer_id
Customer: id, name, address
Result hasMany Prospect.
Prospect belongsTo Customer.
Customer hasMany Prospect.
Everything's ok. If I view the Result, it would display fine along with its related model Prospect.
But in that related model, I'd like to display the customer name instead of customer_id (by looking up). How to do that?
And how to paginate the related model?
Thank you so very much!
add in Prospect belongsTo Result and you will be able to get the info both directions.
if you want to do more crazy things like finding results based on customer name then you might need to read up on the following
linkable behavior
bindModel
adhoc-joins

cakephp - a different has many through relationship

I was wondering if this is possible to do with a has many through
contents orgs folders
id id id
name name title
link
join table - folder_elements
id
element_id
order
contents has many folders through folder_elements
orgs has many folders through folder_elements
So my question is, is it possible to use element_id to store the content.id or the org.id ?
Alex
What you're describing is a sort of HABTM (HasAndBelongsToMany) association. You could define the inter-model associations as you suggest, but there's a pretty significant design flaw: how would you account for a situation where the same ID is used for an orgs record and a contents record, and wish to associate them with the same folder record? It would be impossible to differentiate between the two in your joining table.
There are a number of ways to work around this, but they require more program logic or a more disorganised database schema that presents challenges in maintainability.
The more elegant, robust solution is to rationalise your database structure. If there's no pressing need to have One Join Table to Rule Them All, you could design your model associations like this:
Content hasMany ContentsFolder belongsTo Folder
Folder hasMany ContentsFolder belongsTo Content
Org hasMany OrgsFolder belongsTo Folder
Folder hasMany OrgsFolder belongsTo Org
This is the internal structure of a HABTM association defined explicitly so you can define fields in the joining table. Your contents and folders tables would remain the same, but your two joining tables would look like:
contents_folders
-> id
-> content_id
-> order
orgs_folders
-> id
-> org_id
-> order
Unfortunately, yes, this would require defining five models instead of three, but such are the limitations of CakePHP's object-relational modelling.

Dynamic fields on insert/edit form

let's say that i have 3 tables:
books
properties
book_properties
of course, i would like that when i want to insert new book (or update existing), to fill the form.
fields that exist on form have to be defined as records in table properties.
when i fill up those fields, data has to be saved in table book_properties.
can you help me by giving some advices and references, how to achieve that?
thank you very much in advance!
You will need to create 3 tables: books (id, author, title, etc.), properties (id, name) and books_properties (id, book_id, property_id, property_value). Notice that the third table must be named books_properties, not book_property. Then you will need to create models for the books and properties tables. See the manual here. Create correct assosiations. Books HasAndBelongsToMany Properties. If you use cake console it will be easier to create models, controllers and views.

One table for uploads for multiple resources in CakePHP

I have CakePHP app in which I'd like to attach gallery to multiple resources. Let's say I've got artists, each one has own gallery. I've got articles, every article has some images attached to it and so on. Now I set up tables like this:
Artists hasMany Artistimages, fields in artistimages table are: id, artist_id, filename, filetype, filesize etc.
Articles hasMany Articleimages, fields in articleimages table are: id, article_id, filename, filetype, filesize etc.
...but this is not how it should be, I think.
Is there possibility to have one table called for example uploads which will contain all images with foreign key pointing to resource its reffering to? How to tell CakePHP which image is coming from which resource?
I'd recommend using the Polymorphic Behavior. I often do this for a Binary model which covers images, documents, etc. These represent the physical files that can be associated with any number of models (photos, applicants, etc.).
The gist of a polymorphic relationship is that the table has 2 additional fields. One field that indicates the name of the model being associated (e.g. Photo, Applicant, etc.) and another for the foreign key value (i.e. the id field in the photos table, for example).
If this was me, I would have an images table, then I would have the Artist and Article hasAndBelongsToMany to Image.
Your HABTM would then have a two join tables artists_images and articles_images, then with any luck, Cake will write into these join tables the relationships between each. So you should end up with the correct things associated with the correct images.
By using the HABTM, you can even have one image associated with an Article and Artist, and the same image associated more than once if you need to.
Hope this makes sense, there is more info on HABTM in the book, http://book.cakephp.org/view/83/hasAndBelongsToMany-HABTM
For all of you looking for working solution using polymorphic behavior and MeioUpload, check out this. I'm using it right now and it seems to work fine.

Resources