web-dev-qa-db-ja.com

Laravelフォームモデルバインディング

私はこの機能について読んでいます: http://laravel.com/docs/html#form-model-binding

そしてそれは本当にすてきに見えますが、私が確信していないことがいくつかあります。

このフォームを処理するには、コントローラーアクションにコードを配置する必要がありますか?それはどのように見えますか?

フォームにバインドするモデル(ユーザー)には、アドレス用の個別のテーブルがあります。そのため、ユーザーモデルのフィールドだけでなく、関連する住所モデルのフィールドにも入力できるようにしたいと思います。 form-model-bindingでそれを行うことができますか、またはフォームを手動で処理する必要がありますか?

または、失敗した場合、ユーザーフィールドにフォームモデルバインディングを使用できますが、アドレスフィールドを手動で処理できますか?

25
eimajenthat

このフォームを処理するために、コントローラーに別のコードは必要ありません。すべての(名前付き)フォーム変数はInput :: all()にあります。

渡すモデル($ user)

_Form::model($user, array('route' => array('user.update', $user->id)))
_

必要なレコードだけで、複数のテーブルが関係している場合は、次のようなことをする必要があります

_$user = User::where('id',$userID)
           ->leftJoin('users_addresses', 'users_addresses.user_id', '=', 'users.id')
           ->first();
_

そして、この合成モデルをForm :: model()に渡します。

入力の命名方法は完全にあなた次第です。フォームを処理するロジックを記述する必要があるからです。しかし、私の意見では、アドレス入力には_users_address[street]_が適しています。これは、アドレス列の配列になり、UserAddressモデルにすぐに渡すことができるためです。

_<html>
    <head>
        <title></title>
    </head>
    <body>
        {{ Form::model($user, array('route' => array('user.update', $user->id))) }}
            {{ Form::label('first_name', 'First Name:', array('class' => 'address')) }}
            {{ Form::text('first_name') }}

            {{ Form::label('last_name', 'Last Name:', array('class' => 'address')) }}
            {{ Form::text('last_name') }}

            {{ Form::label('email', 'E-Mail Address', array('class' => 'address')) }}
            {{ Form::text('email') }}

            {{ Form::label('address[street1]', 'Address (Street 1)', array('class' => 'address')) }}
            {{ Form::text('address[street1]') }}

            {{ Form::label('address[street2]', 'Address (Street 2)', array('class' => 'address')) }}
            {{ Form::text('address[street2]') }}

            {{ Form::label('ddress[city]', 'City', array('class' => 'address')) }}
            {{ Form::text('address[city]') }}

            {{ Form::label('address[state]', 'State', array('class' => 'address')) }}
            {{ Form::text('address[state]') }}

            {{ Form::label('address[Zip]', 'Zip Code', array('class' => 'address')) }}
            {{ Form::text('address[Zip]') }}

            {{ Form::submit('Send this form!') }}
        {{ Form::close() }}
    </body>
</html>
_

コントローラーでdd( Input::all() )を実行すると、次のような結果が得られます。

This is the Input::all() result この結果は、Kintのdd()によって提供されます: https://github.com/raveren/kint 。本当に助かりました。

フォームに単一のモデルのフィールドのみがある場合、更新方法は非常に単純で、次のようになります。

_public function update($id)
{
    $user = User::find($id);

    if (!$user->update(Input::all())) {
        return Redirect::back()
                ->with('message', 'Something wrong happened while saving your model')
                ->withInput();
    }

    return Redirect::route('user.saved')
                ->with('message', 'User updated.');
}
_

少し複雑なフォームでは、コーダーはコントローラーにさらにロジックを追加する必要があります。もう少し研究を行うと、これを実現できると思います。

_public function update($id)
{
    $user = User::find($id);

    $inputs = Input::all();

    if (!$user->update($inputs)) {
            $address = new UserAddress($inputs['address']);

        $user->address()->save($address);

        ...
    }

    ...
}
_

Laravel 5.1では、リレーションモデルバインディングの場合、リレーションテーブルをロードする必要があります。

$user = User::with(['address'])->find($id);

ビューでフィールド名を配列として設定します:

{!! Form::model($user, ['route' => ['user.update', $user->id]]) !!}
    {!! Form::text('address[street]') !!}
    {!! Form::text('address[number]') !!}
{!! Form::close() !!}
2
Dukadin