How to get the Primary ID of a ManyMany join table from a record

Silverstripe Version: 4

I have these two DataObjects, Cart and Product joined by a many_many relation with the following extraFields Fabric, Size, Quantity and Price

The only unique field at any point is the ID. As such, updates are replicated on similar records

How do I get the ID to update the related record?

I’m not fully understanding your question - can you post some code?

I think you might be pushing extraFields to the limit here though… Could you make a CartItem DataObject that mirrors this structure? extraFields can be a bit of a pain to view and edit in SilverStripe, promoting that to a DataObject gives you native scaffolding / modeladmin support etc. and would let you define support methods on the class so might make your life easier.

For a CartID of 19 and ProductID of 7, doing the following update, updates both records in the database, that is, ID => 22 && ID => 23
$update = SQLUpdate::create(’"’. $joinTable . ‘"’)
‘“CartID”’ => $this->cart->ID,
‘“ProductID”’ => $product->ID
‘“Quantity”’ => $totalQty,
‘“Price”’ => $unitPrice * $totalQty

I tried creating another extraField that is unique for a record and that seems to work for now. However, that is an interesting approach @JonoM.

If you’re using SQLUpdate you’re essentially bypassing the ORM, so you’re probably not getting any built-in help from SilverStripe in working with your many_many relationship if you do it this way. From the docs:

Dealing with low-level SQL is not encouraged, since the ORM provides powerful abstraction APIs (see datamodel. Starting with SilverStripe 3, records in collections are lazy loaded, and these collections have the ability to run efficient SQL such as counts or returning a single column.

To add a many_many item and set extra fields through the ORM see this example: Save $many_many_extraFields when adding a DataObject to a list -

I would guess that you can’t have multiple connections between the same product+cart if you do it through the ORM though, so a DataObject joining class might be better in that case.