Yii Framework Forum: Спешна нужда от помощ - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Спешна нужда от помощ Регистрационна форма, която да пише в два модела? Rate Topic: -----

#1 User is offline   veso_i 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 15-September 11

Posted 15 September 2011 - 05:59 PM

Здравейте!

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

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

Имам MySql база данни с три таблици (user, client, contractor) - виж прикачения файл.
Юзърите могат да бъдат или клиенти или контрактори. Реално таблицата user съществува за да могат клиентите и контракторите да се логват в една обща логин форма, която ще проверява за валидност на юзъра в таблицата user.

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

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

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

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

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

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

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

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

Attached File(s)


0

#2 User is offline   genn 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 40
  • Joined: 23-December 10

Posted 16 September 2011 - 10:01 AM

Quote

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

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


Едното няма общо с другото ;).
Една форма може да събмитне информация за колкото си искаш модела, като не е нужно между тях да има каквито и да е връзки.
Най-лесният начин е следният:

http://www.yiiframew...idation-edition

В една форма може да сложиш каквито искаш атрибути от различни модели.
После в контролера създаваш инстанции на всеки модел, който искаш да валидираш и на всеки правиш mass-assignment:

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



Причината това да работи е в начина, по който атрибутите на всеки модел се групират в собствен масив.
Т.е. за горния случай $_POST изглежда примерно така:
$_POST = array( 'Model1' => array( 'attrName1' => 'value 1', 'attrName2' => 'value2' ), 'Model2' => array( 'attrName11' => 'value11' ) );



Това е най-лесният начин, не най-добрият.
Ако имаш много модели, става оплетено. Но за твоя случай би било идеално решение.

В подобни случаи е хубаво да ползваш InnoDB engine и transaction, за да запазиш цялостта на данните.


0

#3 User is offline   veso_i 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 15-September 11

Posted 16 September 2011 - 04:45 PM

Благодаря 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 в моделите), но така и не сработват при мен. Затова ги направих ръчно в контролера. Не знам дали е удачен този вариант!

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

#4 User is offline   genn 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 40
  • Joined: 23-December 10

Posted 16 September 2011 - 06:18 PM

Ами по принцип мисля, че има разни extensions, които се грижат за автоматичното запомняне на relations, но аз не работя много с AR и не знам доколко са читави.
Но самото Yii не може да го направи.
Може да подобриш кода ти по следния начин:
Първо валидирай и двата модела с validate(), а след това ги запомняш един след друг.
Защото сега първо запомняш User, но ако Contractor не се валидира( потребителят не е въвел някое поле ), User ще остане записан без Contractor.
Освен това е добре да се ползват transactions в подобни случаи:

http://www.yiiframew...ng-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
}


0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users