Symfony: sfWidgetFormDoctrineChoice: как получить определенное поле - PullRequest
0 голосов
/ 12 марта 2012

Вот моя проблема, я проверил 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).

Есть ли способ получить поле имени пользователя вместо поля идентификатора? Я действительно не могу изменить базу данных.

Спасибо!

Редактировать: вот что находится внутри 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

И вот теперь метод, используемый в опции 'table_method' для виджета submit_user (кажется, работает отлично, но как я могу использовать этот метод для проверки?):

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 ]

2 голосов
/ 13 марта 2012

Виджет sfWidgetFormDoctrineChoice позволяет передавать необязательный параметр с именем table_method, который позволяет вызывать пользовательский метод в модели пользователя для возврата указанных значений.

- Обновление 3.16.12 -

Мне пришлось добавить некоторый пользовательский код в одну из моих объектных форм из-за того, что Doctrine будет выдавать несколько запросов для одних и тех же данных, поэтому кажется, что следующее изменение будет работать хорошоcase:

$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));
0 голосов
/ 13 марта 2012

Короткий ответ: «Да, вы можете», но здесь недостаточно информации, чтобы помочь.Как был создан модуль?Symfony создал это для вас?Если бы вы это сделали, Symfony создал бы для вас рабочую форму на основе вашей схемы.

...