A couple of years ago I used FuelPHP 1.7.2 to develop a portal for internal use in my company. I recently updated the server and also updated Fuel to 1.8.1, as I'll be doing some further development. Everything worked just fine, but one issue with what it seems the PK being reset when I try to set a value for it at the time of forging a new entry.
if ($val->run($values)) { $order = Model_Order::forge($values);
if ($order and $order->save()) { Message::success(e('Added order #'.$order->id.'.'));
Response::redirect('admin/orders'); }
else { Message::error(e('Could not save order.')); } } else { $errors = $val->error(); foreach($errors as $error) Message::error($error); }
"Id" contains the order #, which is also the PK of the table, and is not and cannot be auto-generated. If I check the content of the $value array, all my 7 elements are correctly there, but if check $order->to_array() after forging, "Id" is blank.
After some code-digging and diff-running between the two versions, I found this was added at the end of the ORM/Model::__construct() method:
// make sure the primary keys are reset foreach (static::$_primary_key as $pk) { $this->_data[$pk] = null; }
If I comment it out, everything works as before, but I don't like the idea of having to do that. Is there any other way to accomplish the same behaviour, being able to set a PK value at the time of forging a new object?
This is by design, it is to prevent creating an ORM object in "new" state with a valid and already existing PK, which will cause an exception when you want to save the object.
Thank you for the explanation, Harro. Coming from 1.7.2, the situation was managed in the code with a good old try-catch and gracefully displaying a message. I'll take note of the the above and proceed to modify my code accordingly so it can be 1.8.1 "compliant".
I started working on the changes today and, even with your suggestion, I'm having the same issue. Looking at the from_array() method, the condition to set the properties checks whether the passed property is a PK or not, and doesn't set it if it is:
if (array_key_exists($property, static::properties()) and ! in_array($property, static::primary_key()))
So, it seems like my only option is to explicitly set the PK, as follows:
I've never bumped into this situation myself, but I understand this is annoying for you. I think people using databases without auto-increment, like PostgreSQL, have the same issue.
I need to have a think about how to address this, perhaps make the check configurable in the model so you can enable/disable PK checks on a per-model basis.
Thank you once again, Harro. The check should be either configurable in the Model (probably the best option, IMHO) or there should be a way to "skip" it, like passing a boolean to forge() and from_array().
In the meanwhile, I'll have some fun adding all my explicit PK sets LOL
Harro, I've been running my development version for the last couple of days with the update you pushed for me, and everything is working perfectly. Thank you very much once again!