Symfony:sfWidgetFormDoctrineChoice:如何检索特定字段

时间:2012-03-12 13:42:43

标签: forms symfony1 doctrine foreign-keys validation

这是我的问题,我检查了API和一些其他网站,但我找不到任何解决方案。

一些背景信息:

Tables:

Resources(submit_user,...);
Users(id, username,...); primary key(id);

In 'Resources': foreign key(submit_user) references Users(id);

Symfony形式:

ResourcesForm

submit_user的小部件和验证器:

'submit_user' => new sfWidgetFormDoctrineChoice(array('model' => 'Users', 'add_empty' => false)) //Alternatively, 'model' =>getRelatedModelName('Users')

'submit_user' => new sfValidatorDoctrineChoice(array('model' => 'Users', 'required' => false))

显然,由于我想按原样提交表单,因为不满足外键约束,所以它不起作用。 (我需要用户名字段,而不是submit_user字段的id。)

有什么办法可以检索用户名字段而不是id字段吗?我真的无法修改数据库。

谢谢!

编辑:这是两个表格的schema.yml里面的内容。

Resources:
  connection: doctrine
  tableName: resources
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: true
      autoincrement: false
    aggregation:
      type: integer(1)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    version:
      type: string(50)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    version_status:
      type: integer(1)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    interactivity_type:
      type: integer(1)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    interactivity_level:
      type: integer(1)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    semantic_density:
      type: integer(1)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    difficulty_level:
      type: integer(1)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    learning_time:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    url:
      type: string(100)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    submit_user:
      type: string(15)
      fixed: false
      unsigned: false
      primary: false
      default: ''
      notnull: true
      autoincrement: false
    submit_date:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      default: '0000-00-00 00:00:00'
      notnull: true
      autoincrement: false
    last_updated:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    active:
      type: integer(1)
      fixed: false
      unsigned: true
      primary: false
      default: '1'
      notnull: true
      autoincrement: false
    type:
      type: integer(1)
      fixed: false
      unsigned: true
      primary: false
      default: '1'
      notnull: false
      autoincrement: false
    catalogue_entry:
      type: string(250)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    author:
      type: string(250)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    publisher_producer:
      type: string()
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    funding_body:
      type: string(250)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    size:
      type: integer(8)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
    duration:
      type: time(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    cost:
      type: integer(1)
      fixed: false
      unsigned: false
      primary: false
      default: '0'
      notnull: true
      autoincrement: false
    copyright:
      type: integer(1)
      fixed: false
      unsigned: false
      primary: false
      default: '0'
      notnull: true
      autoincrement: false
    filename:
      type: string(250)
      fixed: false
      unsigned: false
      primary: false
      default: ''
      notnull: true
      autoincrement: false
    protect:
      type: integer(1)
      fixed: false
      unsigned: false
      primary: false
      default: '0'
      notnull: true
      autoincrement: false
    title:
      type: string(250)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    stat_hits:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    keywords:
      type: string(250)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    password:
      type: string(45)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
  relations:
    ResourceContext:
      local: id
      foreign: id
      type: many
    ResourceDescriptions:
      local: id
      foreign: id
      type: many
    ResourceEndUser:
      local: id
      foreign: id
      type: many
    ResourceLanguages:
      local: id
      foreign: id
      type: many
    ResourceMetadata:
      local: id
      foreign: id
      type: many
    ResourceRelations:
      local: id
      foreign: target
      type: many
    ResourceRelations_2:
      class: ResourceRelations
      local: id
      foreign: source
      type: many
    Users:
      local: submit_user
      foreign: username
      type: one
Users:
  connection: doctrine
  tableName: users
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    username:
      type: string(15)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    role:
      type: string(12)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    firstname:
      type: string(20)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    middlename:
      type: string(20)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    lastname:
      type: string(30)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    email:
      type: string(100)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    created:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
  relations:
    Resources:
      local: username
      foreign: submit_user
      type: many

现在这里是submit_user小部件的'table_method'选项中使用的方法(似乎工作得非常好,但我如何使用此方法进行验证?):

public function getUsernames(){

    $query = Doctrine_Query::create()
            ->select('u.username')
            ->from('Users u')
            ;

    return $query->execute();
}

...我现在如何在ResourcesForm.class.php中使用它:

$choice = new sfWidgetFormDoctrineChoice(array('model' => 'Users', 'table_method' => 'getUsernames', 'order_by' => array('name', 'asc')));
$choices = $choice->getChoices();
$this->widgetSchema['submit_user'] = new sfWidgetFormChoice(array('choices' => $choices));

$this->validatorSchema['submit_user'] = new sfValidatorChoice(array('choices' => $choices));

2 个答案:

答案 0 :(得分:2)

sfWidgetFormDoctrineChoice窗口小部件允许您传递名为table_method的可选参数,该参数允许您在用户模型中调用自定义方法以返回您指定的值。

- 更新3.16.12 -

我必须在我的一个Object Forms中添加一些自定义代码,因为Doctrine会针对相同的数据发出多个查询,因此看起来以下更改在您的情况下运行良好:

$choice = new sfWidgetFormDoctrineChoice(array('model' => $model, 'table_method' => 'getUsernames', 'order_by' => array('name', 'asc')));

// Loads the data once
$choices = $choice->getChoices();

// Lets set the keys the same as the value so when form is bound
//  it should pass valid test AND be able to insert/update accordindly
$choices = array_combine($choices, $choices);

// Notice the switch from sf*FormDoctrineChoice to the default sf*FromChoice API calls
// This is because we already have the data loaded, so no need to call on doctrine's
// versions again

$this->widgetSchema['submit_user'] = new sfWidgetFormChoice(array('choices' => $choices));

// Normally this would have an array_keys() call, but aren't concerned with ids
// we are concerned with user names, so it should be a straight pass through
$this->validatorSchema['submit_user'] = new sfValidatorChoice(array('choices' => $choices));

答案 1 :(得分:0)

简短的回答是“是的,你可以”,但这里没有足够的信息来帮助你。模块是如何创建的?你有symfony为你创建吗?如果你这样做,symfony会根据你的架构为你创建一个工作表单。

相关问题