2012-03-12 2 views
0

Вот моя проблема, я проверил API и кучу других сайтов, говорящих об этом, но я не смог найти какое-либо решение.Symfony: sfWidgetFormDoctrineChoice: как получить определенное поле

Некоторые справочную информацию:

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? Я действительно не могу изменить базу данных.

Спасибо!

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

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

- Update 3.16.12 -

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

$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

Спасибо! Но у меня все еще есть проблема: даже когда table_method работает в виджетах, Symfony по-прежнему пытается поместить идентификатор пользователя в поле ресурсов submit_user, тогда как ожидается имя пользователя.Я думаю, проблема связана с проверкой, но я не знаю, что делать точно (ваша ссылка ничего не упоминает на валидаторе). Можете ли вы мне помочь? – Kantho

+0

Итак, у вас есть рабочий стол table_method? для заполнения виджета именами пользователей, а не user_id? Теоретически все, что вам нужно сделать, это убедиться, что для валидатора используется тот же метод table_method, поэтому, когда форма привязана, он будет проверять на имя пользователя, а не на user_ids. –

+0

Да, рабочий стол table_method работает нормально. (См. Мое редактирование в исходном сообщении). Было бы очень приятно делать то, что вы говорите, но sfValidatorDoctrineChoice не поддерживает параметры table_method. Как я могу проверить? – Kantho

0

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

+0

Модуль Ресурсы были созданы Symfony. Дело в том, что форма не работает, и я ничего не изменил в схеме базы данных или даже в форме, связанной с моделью. Я могу предоставить schema.yml и/или базовую форму, если вы думаете, что это поможет. Благодаря! – Kantho

+0

Да, начнем с вашей схемы ... это всегда хорошее место для начала. Измените исходный вопрос с помощью своей схемы, и мы пойдем оттуда. – Patrick

+0

Ну, я не мог поместить всю схему, поскольку она была довольно большой, но я выбрал часть, связанную с моим делом здесь. Надеюсь, это будет полезно. Еще раз спасибо! – Kantho

Смежные вопросы