How do variable Model names work in CakePHP tables? - cakephp

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. ;)

Related

Database design for classified ad item specification

I'm working on a classified ads site with 12 categories. E.g. category vehicles has items cars, bikes, Commercial Vehicles and spare parts. The following is a flow diagram for posting an ad:
I need to show the specification in the Form Filled section of the above image to the users in dropdown lists in the form when they are posting an advertisement. The car specification will be its color,engine,fuel type.
The ERD is below :
How should this issue be tackled, what are the best practices and is the current design going along the right lines?
On the whole this looks ok. Here are some observations:
likes.iker_id should point at users.id? Just trying to understand your model to start.
I would probably change the pics table to be one pic per row and then add an ordinal for ordering.
One question here is how you intend to look at your graph model. As it is, you might have a graph that could be traversed easily to a depth, a couple deep. I assume you are doing this to recommend ads. If so, I think this is sufficient. If not it would be good to further discuss which rdbms you are targetting.
Hope this helps:
In a simplified case, you will need some extra tables.
So, you are trying to be able to have different specifications for different items in your categories? Or, in other words, it is like having different attributes for different types of products in an e-commerce website.
If that the problem you are tackling, then you should look into the Entity–Attribute–Value (EAV) model that is how the problem is solved. By the way, one of the most popular open source e-commerce engines uses it as well.
i agree look at EAV models...
for some other tables, you have many normalization issues - for example:
you should have a separate address table (not part of the ad)
you should have a picture table (and link those to the ads with another table)
you should have a person table - and link that to the ad as 'owner'
the idea of 'favorite' should also be in this person->ad relationship table as a role or type column

How to model a database structure with repeating fields in every table

I'm in the process of structuring a databasemodel for my new project. For all the entities in my model (which is a cms, and the entities as such f.ex: page, content, menu, template and a bunch of others) they all have in common the same attributes on dates and names.
More specifically each entity contains the following for the dates: IsCreated, IsValidFrom, IsPublished, IsDeleted, IsEdited and IsExpired, and for names: CreatedByNameId, ValidFromByNameId, PublishedByNameId and so on...
I'm going to use EF5 for mapping to objects.
The question is as simple: What is the best way to structure this: Having all the fields in every table (which I am not obliged to...) or to have two separate tables which the other can relate to...?
Thanks in advance /Finn.
First of all - give this a read - http://www.agiledata.org/essays/mappingObjects.html
You really need to think about your queries/access paths. There are many tradeoffs between different implementations.
In reply to your example though,
Given the following setup:
COMMON
ValidFromByNameId
SPECIFIC1
FieldA
SPECIFIC2
FieldB
Querying by the COMMON attributes is easy but you'll have to work some magic when pulling up the subclasses (unless EF5 does it for you)
If the primary questions you're asking are about specific1 and specific2 then perhaps this isn't the right model. having the COMMON table doesn't really buy you much necessary as it will introduce a join to load any Specific1 object. In this case, i'd probably just have duplicate columns.
This answer is intentionally partial as a full answer is better handled by the numerous articles and blogs already out there. Search for "mapping object hierarchies to databases"

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 workaround for model inheritance relationship

From my understanding, cakephp doesn't support database inheritance relationship. However, I want to create a database with different type of Users.
In this case, there are three types of Users: Seller, Customer, and Administrator. Every users should have basic User information such as password, username, etc.
However, each types of users will have its own unique set of datas. For example, seller may have inventory_id while customer may have something like delivery_address, etc.
I have been thinking of creating a workaround to this problem without destroying cakephp convention. I was going to create three additional foreign keys, admin_id, seller_id and customer_id, inside User table, which links to other table. However, knowing that this is an IS-A relationship not HAS-A, I would have to make sure that two of the ids are NULL value. Therefore, this workaround seems ugly to me..
Is there any other simpler, better approach?
For this type of database structure I would probably look at adopting an Entity-Attribute-Value model. This would mean your customer may have a delivery_address and your user may have an inventory_id but as far as your relationship in Cake is concerned your both your user and customer would just have an attribute_id ... you can then create another table that stores what type of attributes are available.
It it's simplest form, your user and customer would be attached to an *attribute_lookup* or *attribute_link* table by a hasMany (probably) relationship. That attribute_lookup/link table would be connected by a belongsTo/hasOne relationship to the actual Attribute Type and Attribute Value models.
Providing that you normalise your tables correctly, you can stick well within Cake relationship conventions.
You can read more about EAV here.
I have been thinking about this problem for some time now, and I have eventually got around to build a solution for it. What I came up with is a new ORM that can be used on top of CakePHP.
It sort of works as CakePHP 3.0 with entities that represent an id/model, but it is much more advanced and supports multi table inheritance and single table inheritance.
Check it out: https://github.com/erobwen/Cream

How to define many-to-many relationship in CakePHP

I have an app in which Users belong to many Categories. So I have a Users table, Categories and Users2Categories table. The Users2Categories table consists of a user_id and category_id. So I guess the question is: do I create a model for Users2Categories? Ultimately, I would like to be able to "find" User objects and have their respective categories attached.
Also, can I define this relationship via the baking console?
Read about HABTM in the cookbook. Rename 'Users2Categories' table to 'categories_users'.
You can bake the models from the console but you must have the correct tables first (see above).
HABTM is definitely the way to go.
Cake will handle the join table for you, provided you adhere to the Cake conventions.
Read the section in the Book linked to by bancer, then read it again. Then read this: http://mrphp.com.au/code/working-habtm-form-data-cakephp which will help you with realworld implementation.
So, you asked two questions and got some good information, but the answers are pretty straightforward:
do I create a model for Users2Categories?
You can, but I wouldn't. Cake will create a model for the join at runtime. Since this model/table exists solely to facilitate the join (i.e. it has no properties or methods of its own), just let Cake do that work for you. As stated by #bancer, though, you will need to name the table according to Cake's convention.
Also, can I define this relationship via the baking console?
No. You can create the model skeleton, but that won't include the definition of any associations. AFAIK, there's no way to do that. Bake the skeleton, flesh it out with associations, etc.
I could not have been more wrong. See comments. Thanks for the education, #bancer and #beporter.

Resources