Laravel5应用程序,如何存储父对象和“一对多”子对象

时间:2017-12-10 01:03:15

标签: php laravel laravel-5

在我的Laravel5应用程序中,我有一对多关系,一个服务(名称,描述,开头,结尾),提供“一对多”时间表(白天,开始,结束)。

Service.php:

class Service extends Model
{
    //

    protected $fillable = [

        'name', 'description', 'begins', 'ends', 'service_schedules'

    ];

    public function service_schedules()
    {
        return $this->hasMany('App\ServiceSchedule');
    }
}

ServiceSchedule.php:

class ServiceSchedule extends Model
{
    //

    protected $fillable = [

        'day', 'begins', 'ends', 'service_id'

    ];
}

我使用下面的表单收集服务/日程表创建的输入。 vue2代码允许我为每个计划添加/删除字段行。

form.blade.php:

<div id="app">
    <div class="clearfix"></div>
    <br/>
    <div class="container">
        <div class="col-md-12">
            <div class="form-group row">
                <label for="name" class="col-sm-2 col-form-label">Name<span style="color:red">*</span></label>
                <div class="col-sm-6">
                    {!! Form::text('name', null, array('placeholder' => 'Name','class' => 'form-control')) !!}
                </div>
            </div>

            <div class="form-group row">
                <label for="description" class="col-sm-2 control-label">Description<span
                            style="color:red">*</span></label>
                <div class="col-sm-6">
                    {!! Form::textarea('description', null, array('placeholder' => 'Description','class' => 'form-control')) !!}
                </div>
            </div>

            <div class="form-group row">
                <label for="begins" class="col-sm-2 control-label">From<span style="color:red">*</span></label>
                <div class="col-sm-6">
                    {!! Form::date('begins', \Carbon\Carbon::now(), array('placeholder' => 'Begins','class' => 'form-control')) !!}
                </div>
            </div>

            <div class="form-group row">
                <label for="ends" class="col-sm-2 control-label">To<span style="color:red">*</span></label>
                <div class="col-sm-6">
                    {!! Form::date('ends', \Carbon\Carbon::now()->addMonths(9), array('placeholder' => 'Ends','class' => 'form-control')) !!}
                </div>
            </div>

            <div class="form-group row">
                <label for="description" class="col-sm-2 control-label">Schedules<span
                            style="color:red">*</span></label>
                <div class="col-sm-6">
                    <table class="table">
                        <thead>
                        <tr>
                            <th scope="col">Day</th>
                            <th scope="col">Start</th>
                            <th scope="col">Finish</th>
                            <th scope="col">Actions</th>
                        </tr>
                        </thead>
                        <tbody>
                        <tr v-for="(n, index) in rows" v-bind:id="index + 1">
                            <td>
                                <select class="form-control" v-model="n.day" v-bind:id="'service_schedules[' + index + '][day]'">
                                    <option value="1">Monday</option>
                                    <option value="2">Tuesday</option>
                                    <option value="3">Wednesday</option>
                                    <option value="4">Thursday</option>
                                    <option value="5">Friday</option>
                                    <option value="6">Saturday</option>
                                    <option value="7">Sunday</option>
                                </select>
                            </td>
                            <td><input class="form-control" type="time" v-model="n.start" v-bind:id="'service_schedules[' + index + '][begins]'" /></td>
                            <td><input class="form-control" type="time" v-model="n.finish" v-bind:id="'service_schedules[' + index + '][ends]'" /></td>
                            <td>
                                <button type="button" name="add-schedule" id="add-schedule" class="btn btn-link"
                                        v-on:click="addRow(index)"><i class="fa fa-plus fa-1x"></i></button>
                                <button type="button" name="remove-schedule" id="remove-schedule" class="btn btn-link"
                                        v-on:click="removeRow(index)"><i class="fa fa-minus fa-1x"></i></button>
                            </td>
                        </tr>
                        </tbody>

                    </table>
                </div>
            </div>

我的ServiceController当前基于表单输入成功存储了一个新服务。 ServiceController.php商店:

public function store(Request $request)

    {

        request()->validate([

            'name' => 'required|min:2',

            'description' => 'required',

            'begins' => 'required|date',

            'ends' => 'required|date|after:start_date'

        ]);

        Service::create($request->all());

        return redirect()->route('services.index')

                        ->with('success','Service created successfully');

    }

由于我是Laravel的新手,我不知道如何修改此代码,以便还根据表单输入保存与服务关联的新计划。有人可以建议吗?或者,有人可以将我推荐给任何我可以用作指导的类似例子吗?

1 个答案:

答案 0 :(得分:0)

我看到了一些问题,我还要强调一些改进。

class Service extends Model
{

    protected $fillable = [

        'name', 'description', 'begins', 'ends', // [1]

    ];

    public function serviceSchedules() // [2]
    {
        return $this->hasMany(ServiceSchedule::class); // [3]
    }
}

[1]首先,您不应在$fillable

中包含任何关系

[2]虽然不是必需的,但您应该尝试关注PSR/2 styleguide。 Laravel非常聪明,能够将方法名称转换为下划线版本(我假设是您的数据库表名称)

[3]使用ServiceSchedule::class以避免拼错关系名称

要创建一个新的模型实例,并且在Laravel中将它与其父项相关联的时间非常简单:

$service->serviceSchedules()->create($request->all());

当您将关系作为函数()调用时,它将不返回计划,而是返回查询构建器。这个构建器已经了解了关系的所有内容,所以你所要做的就是运行create(),它将一个普通数组作为输入。如果您已经拥有ServiceSchedule个实例,则可以使用save()代替create()

无论如何,它会在所有计划实例上为您设置service_id

如果我需要澄清任何内容,请告诉我。