logo
Ask your Symfony questions! Pay money and get answers fast! (more info)

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.

$5
Embedded forms not updating Link Tables

We are trying to tie together a Registration module to use the sfGuardUserPlugin. Below is our schema that we have set up. We have a Profiles table that is used as a link between our Contacts table and the SfGuardUser table. From sfGuardUser to Profile it is a 1:1 and the same goes for Profile to Contacts.

schema.yml

Profiles:
actAs: { Timestampable: ~ }
columns:
sf_guard_user_id: { type: integer(4), notnull: true }
contact_id: {type: integer, notnull: true}
relations:
User:
class: sfGuardUser
foreignAlias: Profile
type: one
foreignType: one
local: sf_guard_user_id
foreign: id
Contacts:
alias: Contact
foreignAlias: Profile
type: one
foreignType: one
local: contact_id
foreign: id

Contacts:
actAs: { Timestampable: ~ }
columns:
first_name: { type: string(50) }
last_name: { type: string(50) }
phone1: { type: string(15) }
phone2: { type: string(15) }
email_address: { type: string(100) }
fax: { type: string(15) }


I'm also including my RegisterForm.class.php, which is the register form that we wish to display to the user when they go to become a new user.


class RegisterForm extends sfGuardUserForm
{
public function configure()
{
unset(
$this['is_active'],
$this['is_super_admin'],
$this['updated_at'],
$this['groups_list'],
$this['permissions_list'],
$this['last_login'],
$this['created_at'],
$this['salt'],
$this['algorithm']
);


//Setup password validation
$this->widgetSchema['password'] = new sfWidgetFormInputPassword();
$this->validatorSchema['password']->setOption('required', true);
$this->widgetSchema['password_confirmation'] = new sfWidgetFormInputPassword();
$this->validatorSchema['password_confirmation'] = clone $this->validatorSchema['password'];

$this->widgetSchema->moveField('password_confirmation', 'after', 'password');

$this->mergePostValidator(new sfValidatorSchemaCompare('password', sfValidatorSchemaCompare::EQUAL, 'password_confirmation', array(), array('invalid'=> 'The passwords you entered do not mat
$this->embedForm('Contacts', new ContactsForm());
}


}


I also have an actions.class.php for my module that deals with saving the information once it has been passed validation.


class registerActions extends sfActions
{
/**
* Executes index action
*
* @param sfRequest $request A request object
*/
public function executeIndex(sfWebRequest $request)
{
$this->form = new RegisterForm();
if($request->isMethod('post'))
{
$this->form->bind($request->getParameter('sf_guard_user'));
if ($this->form->isValid())
{
$this->form->save();

$this->getUser()->signIn($this->form->getObject());
$this->redirect('@homepage');
}
}
}
}


My problem starts to arise when I enter the new user information into the form via the view, and submit it, it goes through fine but the link table between user and contact is not being updated with that new user's user account to their contact row in the Contacts table. I was wondering how I would go about updating that link table on save and if anyone has example code for me that would be awesome.

Thanks.

This question has been answered.

uservices | 07/21/10 at 2:02pm Edit


(4) Responses

See a threaded view of answers?

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

  • avatar
    Last edited:
    07/21/10
    4:22pm
    Jakub Zalas says:

    The problem is that your foreign key is in Profiles so Contacts form doesn't know anything about it. Profiles is saved first so it doesn't get Contacts' id.

    Contacts object needs to be saved first and the id should be passed to Profiles.

    I'd try code below. Note that I didn't test it.


    public function doSave($con = null)
    {
    $this->saveContactsForm($con);

    parent::doSave($con);
    }

    private function saveContactsForm($con = null)
    {
    $forms = $this->getEmbeddedForms();

    if (isset($forms['Contacts']))
    {
    $form = $forms['Contacts'];
    $contacts = $form->getObject()
    $contacts->save($con);
    $this->getObject()->setContacts($contacts);
    }
    }


    Previous versions of this answer: 07/21/10 at 4:22pm

  • avatar
    Last edited:
    07/23/10
    11:59am
    mongabure ibes says:

    In your RegisterForm.class.php you have to overwrite the doSave() method. I tried it.


    public function doSave($con = null)
    {
    // save the sfGuardUser and the Contact
    parent::doSave($con);

    //now you can create the link between Contact and sfGuardUser.
    $profile = new Profiles();
    $profile->setsfGuardUserId($this->getObject()->getId());
    $profile->setContactId($this->embeddedForms['Contacts']->getObject()->getId());
    $profile->save();

    }

    attachment image expert uploaded image

  • avatar
    Last edited:
    07/22/10
    4:16am
    Loban Rahman says:

    Both the answers above are right. The reason that your link table is not being updated is because without a Profile form, doctrine/symfony does not realize that the GuardUser and Contact are actually related. So you have to create and save the Profile object manually in the doSave method.

    However, I must question your data model. You have

    GuardUser <--1-------1--> Profile <--1-------1--> Contact

    where Profile contains nothing but a foreign key to each of GuardUser and Contact. Why not just have
    GuardUser <--1-------1--> Contact.

    In fact, you could have just extended the GuardUser model (in the schema file) to include all the fields in Contact. That's a reduction of two tables (so no joins necessary), and no embedded forms needed either.

    Of course, perhaps you plan to actually have more fields in Profile, and you just haven't included them yet. Even then, the link table still seems unnecessary unless you have a many-to-many relation somewhere.

    Anyway, maybe I'm just trying to steal away the $5 from the good gentlemen above. :-P It's just that I always strive for the correct solution to the entire scenario, rather than just the problem originally posed. :-P

  • avatar
    Last edited:
    07/22/10
    3:10pm
    Damian Martinelli says:

    I'm with Loban Rahman. I think that the table Profile is not needed here.

This question has expired.





Current status of this question: Completed



Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.