Спешна нужда от помощ

Здравейте!

Съвсем от скоро се захванах с Yii и като новобранец веднага изскочи проблем!

От четене на много документация и tutorials напълно се обърках :)

Ето го и проблема:

Имам MySql база данни с три таблици (user, client, contractor) - виж прикачения файл.

Юзърите могат да бъдат или клиенти или контрактори. Реално таблицата user съществува за да могат клиентите и контракторите да се логват в една обща логин форма, която ще проверява за валидност на юзъра в таблицата user.

Регистрационните форми ще бъдат различни за клиента и за контрактора.

При регистрация на клиент формата трябва да записва данни както в таблицата user(email, password…) така и в таблицата client(first_name, last_name…)

При регистрация на контрактор формата трябва да записва данни както в таблицата user(email, password…) така и в таблицата contractor(company, address, city…)

Как да направя регистрационна форма да пише в два модела едновременно при натискане на бутона submit?

Може би таблиците в базата и връзките между тях трябва да се конструират по друг начин!!

Гледах някакви подобни примери, но там не показват моделите и връзките между тях.

При мен все не се получава :)

Ще съм благодарен, ако някой окаже адекватна помощ!

[color="#1C2837"][size="2"]

[/size][/color]

[color="#1C2837"] [/color]

[color="#1C2837"][size=“2”]Едното няма общо с другото ;).[/size][/color]

[color="#1C2837"][size="2"]Една форма може да събмитне информация за колкото си искаш модела, като не е нужно между тях да има каквито и да е връзки.[/size][/color]

[size="2"][color="#1c2837"]Най-лесният начин е следният:[/color][/size]

[size="2"] [/size]

[size="2"][color="#1c2837"]http://www.yiiframew…idation-edition[/color][/size]

[size="2"] [/size]

[size="2"][color="#1c2837"]В една форма може да сложиш каквито искаш атрибути от различни модели.[/color][/size]

[size="2"][color="#1c2837"]После в контролера създаваш инстанции на всеки модел, който искаш да валидираш и на всеки правиш mass-assignment:[/color][/size]

[size="2"] [/size]

[size="2"] [/size]




[size="2"][color="#1c2837"]$model1->attributes = $_POST['Model1'];[/color][/size]

[size="2"][color="#1c2837"]$model2->attributes = $_POST['Model2'];[/color][/size]

[size="2"] [/size]

[size="2"] [/size]

[size="2"][color="#1c2837"]Причината това да работи е в начина, по който атрибутите на всеки модел се групират в собствен масив.[/color][/size]

[size="2"][color="#1c2837"]Т.е. за горния случай $_POST изглежда примерно така:[/color][/size]

[size="2"][color="#1c2837"]




$_POST = array( 'Model1' => array( 'attrName1' => 'value 1', 'attrName2' => 'value2' ), 'Model2' => array( 'attrName11' => 'value11' ) );

[/color][/size]

[size="2"] [/size]

[size="2"][color="#1c2837"]Това е най-лесният начин, не най-добрият.[/color][/size]

[size="2"][color="#1c2837"]Ако имаш много модели, става оплетено. Но за твоя случай би било идеално решение.[/color][/size]

[size="2"] [/size]

[size="2"][color="#1c2837"]В подобни случаи е хубаво да ползваш InnoDB engine и transaction, за да запазиш цялостта на данните.[/color][/size]

[size="2"] [/size]

[size="2"] [/size]

Благодаря genn!

Вече направих формите да работят по начина, който описа.

Проблема беше, че когато се създаде запис в таблицата user неговото ID трябва да се записва и в едната от другите таблици Client или Contractor в полето user_id (foreign key). Мислех си, че има начин това да става автоматично, когато има връзка между таблиците, но го направих по следния начин:

public function actionRegisterContractor()

{


    $model=new User;


    $contractor = new Contractor;





    $this->performAjaxValidation(array($model, $contractor));





    if(isset($_POST['User'], $_POST['Contractor']) )


	{


        $model->attributes = $_POST['User'];


        $model->type = 'contractor';


        $model->created = new CDbExpression('NOW()');


        $model->modified = new CDbExpression('NOW()');


        $contractor->attributes = $_POST['Contractor'];





        if($model->save())


        {


            $contractor->user_id = $model->primaryKey;


            if($contractor->save())


                $this->redirect(array('view','id'=>$model->id));


        }


    }





    $this->render('register_contractor', array('model'=>$model, 'contractor'=>$contractor));





}

Четох също така и някакви примери за автоматично писане на полетата created и modified (чрез rules в моделите), но така и не сработват при мен. Затова ги направих ръчно в контролера. Не знам дали е удачен този вариант!

Благодаря още веднъж!

Ами по принцип мисля, че има разни extensions, които се грижат за автоматичното запомняне на relations, но аз не работя много с AR и не знам доколко са читави.

Но самото Yii не може да го направи.

Може да подобриш кода ти по следния начин:

Първо валидирай и двата модела с validate(), а след това ги запомняш един след друг.

Защото сега първо запомняш User, но ако Contractor не се валидира( потребителят не е въвел някое поле ), User ще остане записан без Contractor.

Освен това е добре да се ползват transactions в подобни случаи:

http://www.yiiframework.com/doc/guide/1.1/en/database.dao#using-transactions

В твоя случай ще бъде нещо подобно:





if ( $model->validate() && $contractor->validate() ) 

{

	$transaction = $connection->beginTransaction();

	try 

	{

		$model->save( false);

		$contractor->user_id = $model->primaryKey;

		$contractor->save( false );


		$transaction->commit();

	}

	catch (Exception $e) { // an exception is raised if a query fails

		$transaction->rollBack();

	}

}

else

{

	// show validation error

}