Встраиваемые формы в Symfony 1.4 не сохраняются должным образом - PullRequest
1 голос
/ 30 декабря 2011

У меня есть следующая модель:

WebPromocion:
  connection: doctrine
  tableName: WebPromocion
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: true
      autoincrement: true
    nombre:
      type: string(100)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    foto:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      notnull: true
      autoincrement: false
    flyer:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      notnull: true
      autoincrement: false
    desde:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    hasta:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    descripcion:
      type: string()
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    status:
      type: string(1)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
  relations:
    WebFoto:
      local: foto
      foreign: id
      type: one
    WebFoto_2:
      class: WebFoto
      local: flyer
      foreign: id
      type: one
    WebPromocion_Producto:
      local: id
      foreign: promocion
      type: many

WebFoto:
  connection: doctrine
  tableName: WebFoto
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: true
      autoincrement: true
    ruta:
      type: string(500)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    archivo:
      type: string(150)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    nombre:
      type: string(255)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    alt:
      type: string(255)
      fixed: false
      unsigned: false
      primary: false
      default: ''
      notnull: true
      autoincrement: false
    width:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      notnull: true
      autoincrement: false
    height:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      notnull: true
      autoincrement: false
    map:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    title:
      type: string(500)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    thumbnail:
      type: string(500)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
  relations:
    WebFotoMap:
      local: map
      foreign: id
      type: one
    WebNoticia:
      local: id
      foreign: foto
      type: many
    WebPromocion:
      local: id
      foreign: foto
      type: many
    WebPromocion_2:
      class: WebPromocion
      local: id
      foreign: flyer
      type: many

Как видите, мой WebPromocion объект имеет два поля, ссылающихся на WebFoto объекты (поле 'foto' и поле 'flyer'). Я пишу форму для WebPromocion, встраивая две формы для WebFoto, одну с именем «foto», а другую с названием «flyer» .... Я отлаживал ее с помощью netbeans, и она, кажется, хорошо конструирует объекты, она сохранить встроенные объекты, но когда он собирается сохранить WebPromocion, запрос sql выглядит следующим образом:

 INSERT INTO WebPromocion (foto, nombre, desde, hasta, descripcion, status,
 flyer) VALUES (?, ?, ?, ?, ?, ?, ?) - (5, prueba, 2011-12-29, 2011-12-29, 
 wepale, A, Array)

Во время отладки я обнаружил, что аргументы, переданные функции, ответственной за выполнение, были неверными:

exec('INSERT INTO WebPromocion (foto, nombre, desde, hasta, descripcion, status,
flyer) VALUES (?, ?, ?, ?, ?, ?, ?)', array('5', 'prueba', '2011-12-29',
'2011-12-29', 'wepale', 'A', array('nombre' => 'radioactivo', 'alt' =>
'radioactivo', 'width' => 100, 'height' => 100, 'title' => 'help!!!', 'maps' =>
array('map' => array('name' => 'map2', 'areas' => array('area_1' => array(
'shape' => 'rect', 'coords' => '0,0,100,100', 'href' => 'google.com', 'alt'
=> 'google', 'title' => 'google', 'id' => null)), 'id' => null)), 'id' =>
null, 'archivo' => object('sfValidatedFile'))))

так, для первого поля внешнего ключа ('foto') он помещает правильное значение (в данном случае '5', которое соответствует id или первичному ключу связанного WebFoto), но для второго один ('flyer'), он помещает массив, представляющий объект WebFoto, вместо его первичного ключа ...

Я не знаю, что делать, чтобы это исправить ... Я пытался использовать пустую форму для встраивания обоих WebFotoForm s, и встраивать эту в WebPromocionForm, но таким образом это даже не сохранить WebFoto объекты ... Я думаю, что проблема может быть даже проблема моделирования, что вместо того, чтобы иметь два внешних ключа ('foto' и 'flyer'), мне пришлось бы иметь отношение многие ко многим ... но это только предположение, и я пытаюсь избежать изменений в моей модели ...

1 Ответ

1 голос
/ 22 июня 2012

Я думаю, что ваша модель немного грязная (на самом деле, я думаю, что это какой-то автоматически сгенерированный schema.yml). Может быть, какая-то информация отсутствует (как субъект Producto). Вот несколько советов, которые могут помочь вам определить вашу модель вручную и упорядоченно (в предположении Doctrine 1.2):

  • не определять столбцы идентификаторов. Доктрина создаст для вас, как бигинт, ПК и ИИ.
  • не использовать столбцы или отношения с именем, оканчивающимся на «_NN». Доктрина имеет некоторые проблемы с методами получения и установки.
  • оканчивайте имя столбца FK на "_id"
  • определяют только отношения 1-n, 1-1 и n-m, отношения n-1 должны быть определены в объекте противоположной модели, а для получения обратного доступа используется foreignAlias.
  • 1-n отношение: определить «имя», «onDelete», «local», «foreign» и «foreignAlias». Если имя отношения это не упомянутое имя модели сущности, добавьте «класс» для этого определения. Помните, что «name» и «foreignAlias» становятся получателем / установщиком записей и соединителем запросов.
  • 1-1 отношение: то же самое 1-n, но с type = "one" и единственным зарубежным Alias ​​
  • n-m отношение: определить «имя», «класс», «refClass», «местный» и «иностранный». Определите отношение в обоих объектах как n-m, и оба полу-1-n отношения в отношении-объект. В отношении n-m локальные и внешние столбцы модели отношений-сущностей указывают на каждую модель.

Ваша модель станет чем-то вроде:

WebPromocion:
  columns:
    nombre: { type: string(100), notnull: true }
    foto_id: { type: integer, notnull: true }
    flyer_id: { type: integer, notnull: false }
    desde: { type: timestamp, notnull: true }
    hasta: { type: timestamp, notnull: true }
    description: { type: clob, notnull: false }
    status: { type: string(1), notnull: true, default: 'X' } # some default value looks great for a status column
  relations:
    WebFoto: { onDelete: CASCADE, local: foto_id, foreign: id, foreignAlias: WebPromociones }
    Flyer: { class: WebFoto, onDelete: SET NULL, local: flyer_id, foreign: id, foreignAlias: WebPromociones }
    Productos: { class: Producto, refClass: WebPromocionProducto, local: webpromocion_id, foreign: producto_id } 

webFoto:
  columns:
    ruta: { type: string(500), notnull: true }
    archivo: { type: string(150), notnull: true }
    nombre: { type: string(255), notnull: true, default: '' }
    width: { type: integer(4), notnull: true }
    height: { type: integer(4), notnull: true }
    map: { type: integer(4), notnull: false }    
    title: { type: string(500), notnull: false }
    thumbnail: { type: string(500), notnull: false }


Producto:
  relations:
    WebPromociones: { class: WebPromocion, refClass: WebPromocionProducto, local: producto_id, foreign: webpromocion_id } 

WebPromocionProducto:
  columns:
    producto_id: { type: integer, notnull: true }
    webpromocion_id: { type: integer, notnull: true }
  relations:
    Producto: { onDelete: CASCADE, local: producto_id, foreign: id, foreignAlias: WebPromocionesProductos }
    WebPromocion: { onDelete: CASCADE, local: webpromocion_id, foreign: id, foreignAlias: WebPromocionesProductos }

на основе имени отношения (левая часть от ":") с любым объектом $ webPromocion, который вы можете сделать (

$webPromocion->getWebFoto(), ->getFlyer(), ->getProductos().

в любом запросе таблицы webPromocion вы можете сделать

->innerJoin('wp.WebFoto wf'), ->innerJoin('wp.Flyer'), ->innerJoin('wp.Productos')

на основе foreignAlias, с любым объектом $ webFoto, который вы можете сделать:

$webFoto->getWebPromociones()

и в любом запросе к таблице webFoto вы можете сделать

->innerJoin('wf.WebPromociones')

Наличие хорошего schema.yml очень важно при разработке приложений symfony1.4-doctrine. Тогда ваш customWebPromocionForm должен выглядеть следующим образом:

class customWebPromocionForm extends WebPromocionForm {
  public function configure() {
    parent::configure();
    unset($this['foto_id'],$this['flyer_id']);
    $foto_object = $this->getObject()->getWebFoto();
    $flyer_object = $this->getObject()->getFlyer();
    $this->embedForm('foto_form', new customWebFotoForm($foto_object));
    $this->embedForm('flyer_form', new customWebFotoForm($flyer_object));
    // of course you should define customWebFotoForm, o simply use the default webFotoForm
  }
}

Вот и все. Он работает, когда вы создаете или редактируете какой-либо WebPromocion.

Всегда помните: «ленивец работает вдвойне», o «el vago trabaja doble». Не используйте автогенераторы схемы.

SFMBE

...