We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Autocomplete forms using ORM and Phalcon Forms

Hello everyone!

Let's say I have two relational tables with the following settings:

users (id, email, pwd) users_info (id, uid, name, phone)

If I do this in my UsersController:

$user = Users::findFirstByXid($id);
$this->view->form = new UsersForm($user, array('edit' => true));

I only see email field autocompleted. That's because to access it I can do $user->email but for get the name, I must do somethign like $user->UsersInfo[0]->name

is there some "magic" wat in Phalcon to achieve this or must I make a manual mapping of the object?

Thanks and please forgive this bad english.



85.5k

1 model = 1 database table

UsersInfo is a relation between 2 models, it should be the way its done, cuz if someone else reads your code they will get confused.



93.7k
Accepted
answer
edited Dec '17

As @Izo said, 1 model = 1 database table. Some time ago I had almost identical situation like you. Here is how I solved the problem back then. If someone else has better solution please share! :)

// Controller code
$form = new \Frontend\Forms\ProfileEdit($obj->getEditInfo());

// Model code (or whatever)
public function getEditInfo()
{
    return $this->modelsManager->createBuilder()
        ->columns([
            'profile.id',
            'profile.names',
            'profile.email',
            'details.phone',
        ])
        ->from(['profile' => 'Models\Profiles'])
        ->leftJoin('Models\ProfileDetails', 'details.profile_id = profile.id', 'details')
        ->where('profile.id = :id:', ['id' => $this->id])
        ->getQuery()->getSingleResult();
}

Basically you have to use the Query Builder to create a single object and pass it as form entity in order to populate all the fields :)

UPDATE: Just in case someone asks: But how do I update the two models (database tables) after form is submitted and valited?

// Controller code
$form = new \Frontend\Forms\ProfileEdit($obj->getEditInfo());
if ($this->request->isPost() AND $this->security->checkToken() AND $form->isValid($this->request->getPost())) {
    $obj->updateProfile($id, $this->request);
}

// Model code (or whatever)
function updateProfile($id, $request)
{
    // Profiles table
    $profile = Profiles::findFirst($id);
    $profile->name = $request->getPost('names', 'striptags');
    $profile->email = $request->getPost('email', 'email');

    // Profile details table
    $details = ProfileDetails::findFirstByProfileId($id);
    $details->phone = $request->getPost('phone');;

    // Try to save and return model errors if any
    if ($profile->save() AND $details->save()) {
        return [];
    } else {
        return array_merge((array) $profile->getMessages(), (array) $details->getMessages());
    }
}