Nesting Models Relations In Forms - Laravel

2019-03-11 12:02发布

In laravel, is there some way of nesting related resources in a form?

Say I have this:

class Person extends Eloquent {
  public function addresses() {
    return $this->hasMany("Address");
  }
}

class Address extends Eloquent {
  public function person() {
    return $this->belongsTo("Person");
  }
}

and I want a Person form to collect information about that Person's Addresses. Does laravel facilitate this in a way that is equivalent to Rails' accepts_nested_attributes_for :address and fields_for :address?

I'd just like something simple where I can include the Address fields with the results of the Person form, since the Address doesn't really exist apart from the Person. Does this make sense?

== EDIT ==

This is hypothetical code

What I'm looking for is something that would resemble this:

{{ Form::model(new Person, array("action" => "admin\PersonController@store", "method" => "POST")) }}

{{ Form::text("name", array(...)) // <input name='person[name]' ... /> }}


{{ Form::email("email", array(...)) // <input name='person[email]' ... /> }}

{{ Form::fields_for("addresses"/* Would be name of relation */) }}

  {{ Form::text("street_address") // <input name='person[addresses][][street_address]' ... /> }}

{{ Form::close_fields() }}

{{ Form::close() }}

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-03-11 12:31

You should manage all of this from your controller. Collect the data from the form and use them as you please:

// Controller Code
$person = new Person(array(
    'field_1' => Input::get('field_1'),
    'field_2' => Input::get('field_2'),
    .............
));
$person->save();

$address = new Address(array(
    'field_x' => Input::get('field_x'),
    'field_y' => Input::get('field_y'),
    .............
));
$person->addresses()->save($address);

See it in the docs

查看更多
成全新的幸福
3楼-- · 2019-03-11 12:33

You are on the right track with the input names.

Form

// Form open, Person fields, etc...

<h2>Addresses</h2>
@foreach ($addresses as $address)

    <fieldset>

        {{ Input::text('addresses['.$address->id.'][address_1]', $address->address_1) }}
        {{ Input::text('addresses['.$address->id.'][address_1]', $address->address_2) }}
        {{ Input::text('addresses['.$address->id.'][city]', $address->city) }}
        {{ Input::text('addresses['.$address->id.'][state]', $address->state) }}
        {{ Input::text('addresses['.$address->id.'][zip]', $address->zip) }}

    </fieldset>

@endforeach

// Form Close

If you want to add addresses you'll need to generate some random key to use instead of the address id. This will keep the fields grouped.

Controller Logic

This is how I would handle input, using 'fillable' to filter the data going into the models.

// Get the Person model, fill, save, etc...

$addressIds = array();
foreach (Input::get('addresses', array()) as $id => $addressData)
{
    $address = Address::find($id) ?: new Address;
    $address->fill($addressData);
    $address->save();
    $addressIds[] = $address->id;
}

$changes = $person->addresses()->sync($addressIds);

// Delete the unused addresses
foreach ($changes['detached'] as $detachedAddressId)
{
    $address = Address::find($detachedAddressId);
    if (!empty($address)) $address->delete();
}
查看更多
Explosion°爆炸
4楼-- · 2019-03-11 12:40

Now you can use the package "modelform" to create a form for various models or even a set of forms for relations.

https://github.com/andersondanilo/modelform

查看更多
登录 后发表回答