Reputation: 4091
I'm having trouble saving data in a belongsToMany association. This is the error I'm getting:
Fatal Error (1): Call to a member function get() on a non-object in [application/vendor/cakephp/cakephp/src/ORM/Association/BelongsToMany.php, line 854]
This is the piece of code causing trouble:
public function add(){
$session = $this->request->session();
$call = $this->Calls->newEntity([
"user_id" => $this->Auth->user("id"),
"customer_id" => $session->read("Customer.id"),
"comment" => $this->request->data["comment"],
"result_id" => $this->request->data["result_id"]
]);
if($this->request->data["result_id"] === 0){
$deliveryMode = $this->request->data["order"]["delivery"]["mode"];
$order = new Order([
"delivery" => $deliveryMode,
"products" => [
"_ids" => [1, 2]
]
]);
if($deliveryMode === 1){
$order->set("smartpost_delivery_id", $this->request->data["order"]["delivery"]["locations"][1]["id"]);
}
$call->order = $order;
}
$result = $this->Calls->save($call);
if($result){
$session->write("Customer.id", null);
echo json_encode(["id" => $result->id]);
} else{
echo json_encode($call->errors());
$this->response->statusCode(400);
}
}
As we can see I'm trying to save a Call
that has an Order
attached to it and the part that is causing trouble is that I'm also trying to attach a list of Products
ids to the Order
to be saved to a jointable. If I remove the product ids, the Call
and the Order
are saved successfully.
4 tables are involved: calls
, orders
, products
, orders_products
. Here's a visual representation of the tables. The table objects' code has been auto-baked by the cake app. If needed, I can provide the code for them. Associations: Calls
hasOne Order
, Orders
belongsToMany Products
Upvotes: 1
Views: 1376
Reputation: 60503
You cannot save with the _ids
key, you'll need entities with the appropriate primary key values.
The special _ids
key is a convenience format that is handled by the marshaller when it converts data into entities. It will fetch the appropriate data from the datasource and replace the association property with a list of entities.
Long story short, do not create the Order
entity manually, let the marshaller do it. You'd nost probably want to do that anyways since you are inserting user data into the entity wich should be validated first, which is why you should also add the smartpost_delivery_id
value to the data before converting it into an entity:
$orderData = [
"delivery" => $deliveryMode,
"products" => [
"_ids" => [1, 2]
]
];
if($deliveryMode === 1) {
$orderData["smartpost_delivery_id"] =
$this->request->data["order"]["delivery"]["locations"][1]["id"];
}
// Adjust the name of the association in case necessary
$order = $this->Calls->association('Orders')->newEntity($orderData);
See also
Upvotes: 3