Using Parse.com "Relations", how do you determine which of the 2 classes should own the Relation?
For example think of WhatsApp groups.
Should User have a relation listing all the groups it subscribes to?
Or should Group have a relation listing all the users in the group?
And, does it make sense to have a relation in each? Duplicating the data?
Depends on if you want to store some metadata in one of the Classes. It is explained quite nicely in this part of the document:
https://parse.com/docs/relations_guide#manytomany-relations
The decision point here is whether you want to attach any metadata to
the relationship between two entities. If you don’t, Parse Relation or
using Arrays are going to be the easiest alternatives. In general,
using arrays will lead to higher performance and require fewer
queries. If either side of the many-to-many relationship could lead to
an array with more than 100 or so objects, then, for the same reason
Pointers were better for one-to-many relationships, Parse Relation or
Join Tables will be better alternatives.
In the whatsapp you have given, Since you have access to user, i think it should be more like what are the groups that user belongs to. Read the many to many relations assuming group as book and users as author. It will make sense
Related
I have multiple Orders which have related Payments and related InvoiceCorrections.
I want to fetch all orders where the
order->payments->sum('amount')differs from(order->amount - order->invoiceCorrections->sum('amount')).
What would be the best way to archive this, while keeping a good performance?
The payments should have their own column containing correction information which gets updated via a model observer, otherwise your queries are going to get very complex and messy very fast.
To explain myself better: the examples on Laravel.com showcase a relation of comments belonging to both videos and posts. However I'm talking about specification: not belonging to, but being a specification of the parent table. (Subtyping) Is using Laravel's Polymorphic Relations still the best approach?
A very basic (and potentially bad) example.
Interesting question.
It is entirely possible to do what you require, with the polymorphic relation that Laravel provides. You however, are referring to table inheritance which is whole other kettle of fish.
You could have your Animal model have a polymorphic relationship that can either be Fish or Mamal, or you could have Fish and Mamal belong to an Animal, and create a pass-through model.
It really depends exactly on how you'll be using this. Will you be going through Animal as in querying the animals table, or will you be going from the children?
I have an issue with a many-to-many polymorphic relationship (diagram below). In a food shop some products have options/variants, e.g. pizza comes in variants of 7inch, 12inch, 16inch. When pizza is added to cart a variant must be selected.
When an order is saved
- bought products (without variants) are saved in the orderables table
- variants that are bought are saved in variant_orderables table
Btw, the pivot tables are called orderables and variant_orderables instead of what you might expect according to Laravel conventions, e.g. "customer_order_product", because in addition to customer_orders, the products and variants are also in a polymorphic relationship with stock_orders (where the shop buys those items from suppliers). I just didn't show all that on the diagram to keep it simple.
Anyway, bought items, be they products or variants, can have "extras" added to them in the order. E.g. A pizza can have extra cheese, or pepperoni as extras (info contained in the extras_groups_offers table).
ordered_extras is where we will list the product or variant id of the extras that have been ordered, along with the orderables or variant_orderables id that the extras are applied on.
So between variants and customer_orders, variant_orderables is the pivot, but then variant orderables has a relationship with extras_groups_offers with ordered_extras as the pivot.
I know I probably need to do something with newPivot, but as this involves a few polymorphic many-to-many relationships, I'm not exactly sure how to go about it. If anyone could give me a simple example solution, I'd be very grateful.
Basically, I am trying to reach a stage where I can eager load all the necessary information for an order, including products/variants ordered, and all the ordered extras for each product/variant that has been ordered. I just don't know how to go about it.
Thanks.
I've overcome the problem by making the orderables and variant_orderables tables as normal models. This means I do have more chaining to do in terms of relationships, but I can at least eager load multiple nested layers easily, e.g. order.orderProducts.extrasGroupsOffers
(P.S. orderables has been renamed to order_product, if you're wondering where that came from)
I have two scenarios that I want to support but I don’t know the best way to design relations in the elasticsearch. I read the entire elasticsearch documentation but I couldn’t find the best way to design types for my scenarios.
Multiple one to many.
Let’s assume that I have the following tables in my relational database that I want to transfer to the elasticsearch:
Transaction table Id User1Id User2Id ….
User table Id Name
Transaction contains two references to User. As far as I know I cannot use the parent->child relation specifying two parents? I need to store transaction and user in separate types because they can be changed separately. I need to be able to search transaction through user details and return users connected with transactions. Any idea how to design such structure in the elastic search?
Many to many
Let’s assume that we have the following tables:
Order Id …
OrderLine OrderId UserId Amount …
User Id Name
Order line is always saved with the order so I thought that I can store order with order lines as a nested object relation but the user must be in the separate table. Is there any way how can I connected multiple users from order line with user type? I assume that I can use application side join but I need to retrieve order and order line always together and be able to search order by user data.
I can use grandparent and grandchildren relations but then I need to make joins in the application. Any idea how to design it in the best way?
In the Doctrine manual, under Constrain relationships as much as possible, it gives the advice "Eliminate nonessential associations" and "avoid bidirectional associations if possible". I don't understand what criteria would make an association "essential".
I say this because it seems that you would often want to go from the One side of a One-to-Many association rather than from the Many side. For example, I would want to get all of a User's active PhoneNumbers, rather than get all active PhoneNumbers and their associated User. This becomes more important when you have to traverse multiple One-to-Many relations, e.g. if you wanted to see all Users with a MissedCall from the last two days (MissedCall->PhoneNumber->User).
This is how the simple case would look with an inverse association:
SELECT * FROM User u
LEFT JOIN u.PhoneNumbers p WITH p.active
It would make it more sensible if there were a way to go across a given relation in the opposite direction in DQL, like the following raw SQL:
SELECT * FROM User u
LEFT JOIN PhoneNumber p ON p.User_id = u.id AND p.active
Can someone explain why they give this advice, and in what cases it would be worth ignoring?
-- Edit --
If there are mitigating factors or other workarounds, please give me simple example code or a link.
I do not see any way to traverse a relation's inverse when that inverse is not defined, so I'm going to assume that building custom DQL is not in fact a solution -- there are some joins that are trivial with SQL that are impossible with DQL, and hydration probably wouldn't work anyway. This is why I don't understand why adding inverse relations is a bad idea.
Using Doctrine, I only define relationships when they're needed. This means that all of the relationships defined are actually used in the codebase.
For projects with a large team working on different areas of the project, not everyone will be accustomed to Doctrine, it's current configuration, and eager/lazy loading relationships. If you define bi-directional relationships where they aren't essential and possibly don't make sense, it could potentially lead to extra queries for data that:
may not be used
may have been selected previously
Defining only essential relationships will allow you greater control over how you and your team traverse through your data and reduce extra or overly large queries
Updated 22/08/2011
By essential relationships, I mean the ones you use. It doesn't make sense to define a relationship you wouldn't use. For example:
\Entity\Post has a defined relationship to both \Entity\User and \Entity\Comment
Use $post->user to get author
Use $post->comments to get all comments
\Entity\User has a defined relationship to both \Entity\Post and \Entity\Comment
Use $user->posts to get all user posts
Use $user->comments to get all user comments
\Entity\Comment only has a relationship to \Entity\User
Use $comment->user to get author
Cannot use $comment->post as I don't retrieve the post it belongs to in my application
I wouldn't think of them as "Inverse" relationships. Think of them as "Bi-directional", if using the data in both directions makes sense. If it doesn't make sense, or you wouldn't use the data that way around, don't define it.
I hope this makes sense
I think this is a great question, and am looking forward to others' answers.
Generally, I've interpreted the advice you cited in the down to the following rule of thumb:
If I don't need to access the (inverse) association inside my entity, then I typically make it unidirectional. In your example of users and (missed) calls, I'd probably keep it unidirectional, and let some service class or repository handle putting together custom DQL for the odd occurrence when I needed to get a list of all users with recent missed calls. That's a case I'd consider exceptional -- most of the time, I'm just interested in a particular user's calls, so the unidirectional relationship works (at least until I've got so many records that I feel the need to optimize).