Say I have models User and Post
Clearly, User hasMany Post
But now I want to have subscriptions.
Do I create a second relationship user/post relationship that is HABTM in addition to the relationship they already have?
I think that you need to create the relation User belongsTo Subscriptions.
I do not see that having a relationship HABTM
You could do this with two different hasMany associations, a new belongsTo association, or a new HABTM association. It really depends on how you want to organize and access your data.
To answer the question you posed in the comments, yes, it's possible to have multiple relationships between the same set of Models. Please read: Multiple relations to the same model from the Cake book.
Of course you can add more than one relation on the same model. You han have: User hasMany Post
User hasMany Subscription
Post belongsTo User
Subscription belongsTo User
On both direction you can get all users's posts and posts that belong to users.
Related
I have 3 model named User, Product and Review. I used one to many relationship between User and Product, on the other hand I use one to many between Product and Review.
I can find related product from user model and find related reviews from product model.
How can I find related product reviews from user model?
You should use has-many-through relationship.
https://laravel.com/docs/9.x/eloquent-relationships#has-many-through
The "has-many-through" relationship provides a convenient way to access distant relations via an intermediate relation.
I'm actually confused about using either hasOne() or belongsTo() relationship. Assuming the relation is 1:1. Then which one?
An invoice hasOne a customer?
An invoice belongsTo a customer?
Noted that I've implemented both, and they works well .. But what's the standard one? When should I use which one?
hasOne can be used in a strong model or entity
belongsTo can be used in a weak model or entity.
I am sure you have an idea of strong and weak entities in database.
you can use invice hasOne(customer) in your case you can not use hasOne() with customer because customer has many invoices so batter use hasOne() with invoice and belongsTo() with customer.
Ex. invoice model
hasOne(customer)
while in customer model
belongsTo(invoice)
It depends on which table has the foreign key.
Imagine a relationship between Person and car.
The Owner can own one Car.
The Car can be owned by one Owner.
So, the Owner hasOne Car, and the car belongsTo an Ownwe. So, the foreign key will go in "car". The car needs to know who it belongsTo.
In your case, the invoice needs to know who it belongs to, so, if a customer can have many invoices, customer hasMany(Invoice::class) and invoices belongsTo(Customer::class).
If your 2 related tables/entities have a relationship as one-to-one they should be defined using hasOne.
If your 2 related tables/entities have a relationship as one-to-many like A has many B, then A should define B as hasMany and B should define A as belongsTo which will be called as One To Many (Inverse)
For your case both models could define each other as hasOne and inverse side of model should define owning model as belongsTo
An invoice hasOne customer , customer belongsTo invoice
A customer hasOne invoice, invoice belongsTo customer
In a one-to-one relationship the table/entity holding the foreign key of the related table/entity is always the owning side of the relation and other will be inverse side of relation.
I'm curious why the Eloquent relationship for hasMany has a different signature than for belongsToMany. Specifically the custom join table name-- for a system where a given Comment belongs to many Roles, and a given Role would have many Comments, I want to store the relationship in a table called my_custom_join_table and have the keys set up as comment_key and role_key.
return $this->belongsToMany('App\Role', 'my_custom_join_table', 'comment_key', 'role_key'); // works
But on the inverse, I can't define that custom table (at least the docs don't mention it):
return $this->hasMany('App\Comment', 'comment_key', 'role_key');
If I have a Role object that hasMany Comments, but I use a non-standard table name to store that relationship, why can I use this non-standard table going one way but not the other?
hasMany is used in a One To Many relationship while belongsToMany refers to a Many To Many relationship. They are both distinct relationship types and each require a different database structure - thus they take different parameters.
The key difference is that in a One To Many relationship, you only need the two database tables that correspond to the related models. This is because the reference to the relation is stored on the owned model's table itself. For instance, you might have a Country model and a City model. A Country has many cities. However, each City only exists in one country. Therefore, you would store that country on the City model itself (as country_id or something like that).
However, a Many To Many relationship requires a third database table, called a pivot table. The pivot table stores references to both the models and you can declare it as a second parameter in the relationship declaration. For example, imagine you have your City model and you also have a Car model. You want a relationship to show the types of cars people drive in each city. Well, in one city people will drive many different types of car. However, if you look at one car type you will also know that it can be driven in many different cities. Therefore it would be impossible to store a city_id or a car_id on either model because each would have more than one. Therefore, you put those references in the pivot table.
As a rule of thumb, if you use a belongsToMany relationship, it can only be paired with another belongsToMany relationship and means that you have a third pivot table. If you use a hasMany relationship, it can only be paired with a belongsTo relationship and no extra database tables are required.
In your example, you just need to make the inverse relation into a belongsToMany and add your custom table again, along with the foreign and local keys (reversing the order from the other model).
Try to understand with text and a figure.
One to One(hasOne) relationship:
A user has(can have) one profile. So, a profile belongs to one user.
One to many(hasMany):
A user has many(can have many) articles. So, many articles belong to one user.
Many to many(BelongsToMany):
A User can belong to many forums. So, a forum belongs to many users.
I was wondering if there is a smart way of having several common columns to different tables in CakePhP. I could use a common table having relationships to these tables, but is there a behavior or similar mechanism for which I can have:
Users
Customers
CommonPersonalFields
And have some common fields in the third table, fetched automatically by cake. In this way you could also have common views for those fields, included in the other tables views.
This is done with Model Associations in CakePHP. In this scenario, your models would be User, Customer, and PersonalData, and your associations are User hasOne PersonalData, Customer hasOne PersonalData, and if you want the association to be linked from both directions, PersonalData belongsTo User and PersonalData belongsTo Customer.
I'm creating a project management system which projects are assigned to users
What's the difference between creating a Model ProjectsUser and defining 2 $belongsTo relationship and defining HABTM relationships in both Project and User models? What would be the most correct way, though? And how do I save the data in the projects_users table?
From my experience, if you want to be able to save or delete rows only from the join table (the one with 2 IDs), then it is much more simple using three models associated through both a hasMany and a belongsTo association.
You can also retrieve data from the join table directly and do the queries you want much more easily
This is what CakePHP documentation says refering to HABTM and saving data:
However, in most cases it’s easier to make a model for the join table and setup hasMany, belongsTo associations as shown in example above instead of using HABTM association.
Here you can find more the full text:
http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated
I have used this method for a "reads" table (with post_id and user_id) as well as for subscriptions and similar kind of relationships.
The first way is called "hasAndBelongsToMany" [details here].
The second is called "hasMany through" [details here].
The second link relating to "hasMany through" has details and a lengthy explanation about when and why you would want to use it.
Not sure about the specifics of cakephp, but in general defining the relation model explicitly gives you more control over it, for instance if you wanted to do some validation or add callbacks on creation of this relationship.