adamwathan / bootforms

Rapid form generation with Bootstrap 3 and Laravel.
MIT License
417 stars 103 forks source link

how to bind a model use bootforms #15

Closed yuanaichi closed 10 years ago

adamwathan commented 10 years ago

Check the docs for the underlying form package: https://github.com/adamwathan/form/blob/master/readme.md#model-binding

BootForm::open();
BootForm::bind($model);
BootForm::text('Email', 'email');
BootForm::close();
benelang commented 9 years ago

Is it possible to use this for combined models? This means i have a Person model which is extended by a Participant Model. I want to edit data from Person and Participant in one edit view. The code above didn't work in my case?

adamwathan commented 9 years ago

Hey @benelang! Can you give a bit more detail? If you have this...

class Participant extends Person
{
    // ...
}

...I don't see why it wouldn't work to bind a Participant instance to the form. Are they two separate models, and if so how were you trying to set it up exactly?

djeckle commented 9 years ago

Hey @adamwathan, I am taking this over from @benelang.

We are looking into binding via a relationship like this: https://github.com/laravel/framework/pull/2036

In short the model looks like this (extending eloqeunt):

class Person {
    public function participant() {
        return $this->hasOne('Participant');
    }
    // email attribute here
}
class Participant {
    public function person() {
        return $this->belongsTo('Person');
    }
// ...
}

In normal laravel form model binding it is possible to bind the relationship Form::text('person[email]'). Is that possible with your forms too? We can't find it in your docs and try and error gives us a negative result. ;)

Thanks in advance!

adamwathan commented 9 years ago

Not possible at the moment but interesting idea for a future enhancement.

Normally I would create a form object for something like this, that aggregates the data from multiple models into one new object that represents all the data needed for the form and bind that. Decent example of doing it in Rails here.

benelang commented 9 years ago

Hi @adamwathan,

thank you for your quick response! Do you have some plans if you want to integrate it and how much time this may take?

Thanks in advance!

adamwathan commented 9 years ago

I like the idea but can't promise to integrate it any time soon.

In the mean time I would recommend passing an object to the view that contains the fields you need:

public function edit($id)
{
    $participant = Participant::find($id);
    $formObject = (object) [
        'name' => $participant->name;
        'email' => $participant->person->email;
    ];
    return View::make('participants.edit', ['participant' => $formObject]);
}

Or alternatively add an email accessor to the participant to avoid fetching it through the person. This helps you avoid a Law of Demeter violation as well, which reduces duplication of knowledge in your design.

class Participant
{
    public function person()
    {
        return $this->belongsTo('Person');
    }

    public function getEmailAttribute()
    {
        return $this->person->email;
    }
}