неожиданное поведение newObject

Пишу в раздел вопросы, т.к. в раздел «для разработчиков» рейтинг недостаточен

Потратив некоторое время на поиск бага, решил поделить с сообществом. Может кому то время сэкономит.

такое не работает
$xpdo->newObject($className, array('id' => $id);
а такое работает
$obj = $xpdo->newObject($className);
$obj->id = $id;
Причина
class xPDOObject {
...................................
public function fromArray($fldarray, $keyPrefix= '', $setPrimaryKeys= false, $rawValues= false, $adhocValues= false) {
...................................
$key = $this->getField($key);
if (isset ($this->_fieldMeta[$key]['index']) && $this->_fieldMeta[$key]['index'] == 'pk') {
    if ($setPrimaryKeys) {
        if (isset ($this->_fieldMeta[$key]['generated'])) {
            $generatedKey= true;
        }
        if ($this->_new) {
            if ($rawValues || $generatedKey) {
                $this->_setRaw($key, $val);
            } else {
                $this->set($key, $val);
            }
            $pkSet= true;
        }
    }
}
Поэтому если в массиве есть ключ совпадающий с pk, то он игнорируется.
Возможность передать $setPrimaryKeys=true из newObject отсутствует
Сообщений об ошибке нет.

ps. Такое тоже не работает
$obj = $xpdo->newObject($className, $id);
Сообщений об ошибке нет.

pps.
github.com/bezumkin/Tickets/blob/32b75aad0f7bbf7407efd4fe8206c1e0e767eb6e/core/components/tickets/model/tickets/ticket.class.php#L664-L667

ppps. Для таблиц а-ля client_properties удобно юзать id совпадающий с client
Интересует мнение, в целом нормальная практика задавать id или лучше такого избегать?
Дмитрий Ломакин
09 ноября 2018, 01:11
modx.pro
1 136
0

Комментарии: 8

Наумов Алексей
09 ноября 2018, 08:26
+1
Поле id генерируется автоматически, причем на уровне базы данных, я думаю.
Задавать нельзя, как вы проблему совпадающих id решать хотите?
    Василий Наумкин
    10 ноября 2018, 16:42
    +2
    Вообще-то, можно.
    $obj = $modx->newObject('xPDOObject');
    // после создания нового объекта можно выставлять любое поле
    $modx->set('id', 10);
    // или
    $modx->fromArray(['id' => 10], '', true); // 3й параметр позволяет менять первичный ключ

    Именно так msProductData привязывается к msProduct — у них всегда одинаковые id. А по ссылке на Tickets была опечатка, я её уже поправил.
    Дмитрий Ломакин
    10 ноября 2018, 04:13
    0
    у меня этот кусок использовался при импорте из 1с
    поле id = id в 1с
    при таком раскладе «проблемы совпадающих id» просто не могло возникнуть от слова совсем.
      Алексей Шумаев
      10 ноября 2018, 12:00
      0
      При импорте можно использовать варианты:
      • артикул
      • TV-поле
      • расширить modResource или msProduct, добавив своё поле. Я использую extID.
      id таблиц modx использовать нельзя, иначе всегда будут «сюрпризы».
        Дмитрий Ломакин
        11 ноября 2018, 19:03
        0
        У меня свои таблицы.

        Использовать extID можно, но тогда:
        на странице товара выводить какой код? extID?
        в URL на странице товара какой код использовать? extID?
        В базе потом искать тоже по extID? индекс делаем по extID?
        в финале ID где будет использоваться? нигде?

        а если везде вышеуказанном использовать id, то сотрудникам неудобно
        в 1с один код, на сайте другой!
      Сергей Шлоков
      11 ноября 2018, 07:46
      0
      Действительно, и почему же newObject не сохраняет id? Может потому, что он предназначен для нового объекта. Ибо для существующего объекта есть getObject. А если нужно создать новый при условии, что такого ещё нет или обновить существующий, то делается это как написал выше Василий.

      Пишу в раздел вопросы, т.к. в раздел «для разработчиков» рейтинг недостаточен
      Самое место в разделе «Вопросы».
        Дмитрий Ломакин
        11 ноября 2018, 18:55
        0
        Если поле PK всегда readOnly, то такое поведение newObject оправдано.
        Если в оф. документации было бы это оговорено, то такое поведение newObject оправдано.
        Если newObject игнорирует id и ругается на это в логах, то такое поведение приемлемо

        текущая ситуация меня удивила, понять ее удалось только из исходников.
        «решил поделить с сообществом. Может кому то время сэкономит.»

        ИМХО я все сделал верно.
          Сергей Шлоков
          11 ноября 2018, 21:46
          0
          ИМХО я все сделал верно.
          Разбираться всегда лучше, чем не разбираться. Я так и научился.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        8