symfony 1.4中的嵌入式表单无法正确保存 [英] Embedded forms in symfony 1.4 not saving properly

查看:97
本文介绍了symfony 1.4中的嵌入式表单无法正确保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下模型:

  WebPromocion:
连接:教义
tableName:WebPromocion
列:
id:
类型:integer(4)
固定:false
无符号:true
主要:true
自动递增:true
nombre:
类型:string(100)
固定:false
unsigned:false
primary:false
notnull:true
自动递增:false
照片:
类型:整数(4)
固定:false
unsigned:true
primary:false
notnull:true
自动递增: false
传单:
类型:integer(4)
固定:false
unsigned:true
primary:false
notnull:true
自动递增:false
desde:
类型:timestamp(25)
固定:false
unsigned:false
primary:false
notnull:true
自动递增:false
hasta:
类型:timestamp(25)
固定:false
unsigned:false
primary:false
notnull:true
自动递增:false
描述:
类型:string()
固定:false
无符号:false
主要:false
notnull:false
自动递增:假
状态:
类型:字符串(1)
固定:假
无符号:假
主要:假
notnull:真
自动递增:错误
关系:
WebFoto:
本地:foto
国外:id
类型:一个
WebFoto_2:
类:WebFoto
本地:传单
国外:id
类型:一个
WebPromocion_Producto:
本地:id
国外:promocion
类型:许多

WebFoto:
连接:教义
表名:WebFoto
列:
id:
类型:整数( 4)
固定:false
无符号:是
主要:是
自动递增:是
ruta:
类型:string(500)
固定:假
无符号:假
主变量:假
notnull:真
自动递增:假
档案:
类型:字符串(150)
固定:假
无符号:假
主变量:假
notnull:真
自动递增:假
标称:
类型:string(255)$ b固定的$ b:否
无符号:否
主变量:否
notnull:真的
自动递增:否
alt:
类型:string(255)
固定:false
无符号:false
主:false
默认值:''
notnull:true
自动递增:false
宽度:
类型:integer(4)
固定:false
unsigned:true
primary:false
notnull:true
自动递增:假
高度:
类型:整数(4)
固定:假
无符号:真
主:假
notnull:真
自动递增:假
映射:
类型:整数(4)
固定:假
无符号:真
主:假
notnull:假
自动递增:false
标题:
类型:string(500)
固定:false
无符号:false
主要:false
notnull:false
自动递增:假
缩略图:
类型:字符串(500)
固定:假
无符号:假
主要:假
notnull:假
自动递增:false
关系:
WebFotoMap:
本地:地图
国外:id
类型:一个
WebNoticia:
本地:id
外国:foto
类型:many
WebPromocion:
本地:id
外国: foto
类型:许多
WebPromocion_2:
类:WebPromocion
当地:id
外国:传单
类型:许多

如您所见,我的 WebPromocion 对象有两个引用<$ c $的字段c> WebFoto 对象( foto字段和 flyer字段)。我为 WebPromocion 编写了一个表单,为 WebFoto 嵌入了两种表单,一种称为 foto,另一种称为 flyer '....我已经使用netbeans对其进行了调试,它似乎可以很好地构造对象,可以保存嵌入的对象,但是当要保存 WebPromocion 时,则sql查询如下:

 插入WebPromocion(foto,nombre,desde,hasta,cricripion,status,
Flyer)值(?,?,?,?,?,?,?)-(5,prueba,2011-12-29,2011-12-29,
wepale,A,Array)

在调试时,我发现传递给负责执行的函数的参数是错误的:

  exec('INSERT INTO WebPromocion(foto,nombre,desde,hasta,descripcion,status,
Flyer)值(?,?,? ,?,?,?,?)',array('5','prueba','2011-12-29',
'2011-12-29','wepale','A',array ('nombre'=>'radioactivo','alt'=>
'radioactivo','width'=> 100, ‘身高’=> 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',它与相关的 WebFoto 的I​​D或主键相对应),但在第二个值('flyer' '),它将放置表示 WebFoto 对象的数组,而不是其主键...



不知道该怎么做才能解决此问题...我尝试使用一个空表单同时嵌入两个 WebFotoForm s,并将此嵌入到中WebPromocionForm ,但是这样甚至不保存 WebFoto 对象...我认为问题可能甚至是建模问题,相反关于具有两个外键( foto和 flyer),我将必须具有多对多的关系...但这只是一个假设,我正尝试避免更改模型。

解决方案

我认为您的模型有点混乱(实际上,我认为这是一些自体基因评级为schema.yml)。也许缺少一些信息(作为Producto实体)。
这里有一些技巧可能可以帮助您手动和有序地定义模型(假设Doctrine 1.2):




  • 不要定义id列。主义为您创建了bigint,PK和AI。

  • 不要使用名称以 _NN结尾的列或关系。原则对getter和setter方法有一些麻烦。

  • 用 _id结尾FK列名

  • 仅定义1-n,1-1和nm关系,n-1关系应为

  • 1-n关系:定义名称, onDelete,本地,外国和 foreignAlias 。如果关系的名称不是所引用的实体模型名称,则为该定义添加类。请记住,名称和 foreignAlias成为记录的获取器/设置器和查询联接器。

  • 1-1关系:idem 1-n,但具有type = one和单数的Alias别名

  • nm关系:定义名称, 类, refClass,本地和外国。将两个实体中的关系都定义为n-m,并将两个半1-n关系都定义为关系实体。在nm关系中,本地和外部是指向每个模型的关系实体模型列。



您的模型将变成类似:

  WebPromocion:
列:
nombre:{类型:string(100),notnull:true }
foto_id:{类型:整数,notnull:真}
Flyer_id:{类型:整数,notnull:否}
desde:{类型:时间戳,notnull:真}
hasta:{类型:时间戳,notnull:true}
描述:{类型:clob,notnull:false}
状态:{类型:string(1),notnull:true,默认值: X} #状态栏
的关系:
WebFoto:{onDelete:CASCADE,本地:foto_id,国外:id,国外别名:WebPromociones}
Flyer:{类:WebFoto, onDelete:SET NULL,本地:flyer_id,外部:id,外部别名:WebPromociones}
Productos:{类:Producto,refClass:WebPromocionProducto,本地:webpromocion_id,外部:prod ucto_id}

webFoto:
列:
ruta:{类型:string(500),notnull:true}
archivo:{类型:string(150), notnull:true}
nombre:{类型:string(255),notnull:true,默认值:}
width:{类型:integer(4),notnull:true}
高:{类型:integer(4),notnull:true}
映射:{类型:integer(4),notnull:false}
标题:{类型:string(500),notnull:false}
缩略图:{类型:string(500),notnull:false}


产品:
关系:
WebPromociones:{类:WebPromocion,refClass: WebPromocionProducto,本地:producto_id,外部:webpromocion_id}

WebPromocionProducto:
列:
producto_id:{类型:整数,notnull:true}
webpromocion_id:{类型:整数,notnull:true}
关系:
Producto:{onDelete:CASCADE,本地:producto_id,国外:id,foreignAlias:WebPromocionesProductos}
WebPromocion:{onDelete:CASCA DE,本地:webpromocion_id,外国:id,外国别名: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')
b具有良好的schema.yml,在开发symfony1.4原理应用程序时至关重要。
然后,您的customWebPromocionForm应该如下所示:

  class customWebPromocionForm扩展了WebPromocionForm {
公共函数configure() {
parent :: configure();
未设置($ this ['foto_id'],$ this ['flyer_id']);
$ foto_object = $ this-> getObject()-> getWebFoto();
$ flyer_object = $ this-> getObject()-> getFlyer();
$ this-> embedForm(’foto_form’,新的customWebFotoForm($ foto_object));
$ this-> embedForm(’flyer_form’,新的customWebFotoForm($ flyer_object));
//当然,您应该定义customWebFotoForm,或者只需使用默认的webFotoForm
}
}

仅此而已。



永远记住:懒惰的人双倍起作用, el vago trabaja doble。不要使用架构自动生成器。



SFMBE


I have the following model:

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

As you can see, my WebPromocion object has two fields referencing WebFoto objects ('foto' field, and 'flyer' field). Im writing a form for WebPromocion, embedding two forms for WebFoto, one called 'foto' and the other called 'flyer'.... I have debugged it with netbeans, and it seems to construct well the objects, it save the embedded objects, but when it is going to save the the WebPromocion, the sql query is the following:

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

While debugging, i found that arguments passed to the function responsible of executing were wrong:

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'))))

so, for the first foreign key field ('foto'), it places the correct value ('5' in this case, which corresponds to the id or primary key of the related WebFoto), but for the second one ('flyer'), it places the array representing the WebFoto object, instead of its primary key...

I don't know what to do to fix this... I have tried using an empty form to embed both WebFotoForms, and embedding this one in the WebPromocionForm, but this way it doesn't even save the WebFoto objects... I think the problem may be even a modelation problem, that instead of having the two foreign keys ('foto' and 'flyer'), i would have to have a many-to-many relationship... but that's just an assumption , and I'm trying to avoid changes in my model...

解决方案

I think your model it's a little messy (actually, I think it's some autogenerated schema.yml). Maybe there's some info missing (as Producto entity). Here some tips that maybe can help you define your model manually and orderly (assuming Doctrine 1.2):

  • dont define ids columns. Doctrine create it for you as an bigint, PK and AI.
  • dont use columns or relations with name ended "_NN". Doctrine has some troubble with the getter and setter methods.
  • end your FK column name with "_id"
  • define only 1-n, 1-1 and n-m relations, n-1 relations should be defined in the opposite model entity, and use the foreignAlias for accesing inversely.
  • 1-n relation: define "name", "onDelete", "local", "foreign" and "foreignAlias". If the name of the relation it's not the referred entity model name, add the "class" for that definition. Remember that "name" and "foreignAlias" become the record getter/setter and the query joiner.
  • 1-1 relation: idem 1-n, but with type="one" and singular foreignAlias
  • n-m relation: define "name", "class", "refClass", "local" and "foreign". Define the relation in both entities as n-m, and both semi 1-n relation in the relation-entity. In the n-m relation, local and foreign are the relation-entity model columns that point to each model.

You model will become something like:

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 }

based on the relations name (the left part from ":"), with any $webPromocion object you can do (

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

in any webPromocion table query, you can do

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

based on the foreignAlias, with any $webFoto object you can do:

$webFoto->getWebPromociones()

and in any webFoto table query, you can do

->innerJoin('wf.WebPromociones')

Having a nice schema.yml it's critical when you are developing symfony1.4-doctrine apps. Then, your customWebPromocionForm should looks like:

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
  }
}

That's all. It works when you are creating or editing some WebPromocion.

Always remember: "the lazy man works doubly", o "el vago trabaja doble". Don't use schema autogenerators.

SFMBE

这篇关于symfony 1.4中的嵌入式表单无法正确保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆