后盾网lavarel视频项目---lavarel多表关联一对多操作实例
一、总结
一句话总结:
1、一对多中多那个部分的数据前端通过json弄到服务器
2、所有通过一操作多的时候,都要用上模型中定义的那个方法:$lesson->videos()->create($video);
1、页面直接通过一对多中的一找到多的数量?
控制器中:$data=Lesson::get();
视图中:{{$d->videos()->count()}}
控制器中 public function index() { $data=Lesson::get(); //dd($data->toArray()); return view('admin.lesson.index',compact('data')); } 视图中 <tr> <td>{{$d['id']}}.</td> <td>{{$d['title']}}</td> <td>{{$d->videos()->count()}}</td>
2、一对多模型中多对应部分数据通过json传到服务器?
1、转成数组:$videos=json_decode($request['videos'],true);
2、所有通过一操作多的时候,都要用上模型中定义的那个方法:$lesson->videos()->create($video);
//videos数据过来的时候是json数据,true表示转成数组而非对象 $videos=json_decode($request['videos'],true); foreach ($videos as $video){ $lesson->videos()->create($video); }
二、lavarel多表关联一对多操作实例
1、模型
app/Model/Lesson.php
1 <?php 2 3 namespace AppModel; 4 5 use IlluminateDatabaseEloquentModel; 6 7 class Lesson extends Model 8 { 9 /** 10 * 与视频表模型的一对多关联 11 * @return IlluminateDatabaseEloquentRelationsHasMany 12 */ 13 public function videos(){ 14 return $this->hasMany(Video::class); 15 } 16 }
app/Model/Video.php
1 <?php 2 3 namespace AppModel; 4 5 use IlluminateDatabaseEloquentModel; 6 7 class Video extends Model 8 { 9 protected $guarded=[]; 10 }
2、控制器
app/Http/Controllers/Admin/LessonController.php
1 <?php 2 3 namespace AppHttpControllersAdmin; 4 5 use AppModelLesson; 6 use IlluminateHttpRequest; 7 use AppHttpControllersController; 8 9 class LessonController extends CommonController 10 { 11 /** 12 * Display a listing of the resource. 13 * 14 * @return IlluminateHttpResponse 15 */ 16 public function index() 17 { 18 $data=Lesson::get(); 19 //dd($data->toArray()); 20 return view('admin.lesson.index',compact('data')); 21 } 22 23 /** 24 * Show the form for creating a new resource. 25 * 26 * @return IlluminateHttpResponse 27 */ 28 public function create() 29 { 30 // $d=Lesson::find(1)->videos()->get(); 31 // dd($d->toArray()); 32 return view('admin.lesson.create'); 33 } 34 35 /** 36 * Store a newly created resource in storage. 37 * 38 * @param IlluminateHttpRequest $request 39 * @return IlluminateHttpResponse 40 */ 41 public function store(Request $request,Lesson $lesson) 42 { 43 //dd($request->toArray()); 44 $lesson['title']=$request['title']; 45 $lesson['introduce']=$request['introduce']; 46 $lesson['preview']=$request['preview']; 47 $lesson['is_commend']=$request['is_commend']; 48 $lesson['is_hot']=$request['is_hot']; 49 $lesson['click']=$request['click']; 50 $lesson->save(); 51 52 //videos数据过来的时候是json数据,true表示转成数组而非对象 53 $videos=json_decode($request['videos'],true); 54 foreach ($videos as $video){ 55 $lesson->videos()->create($video); 56 } 57 return redirect('/admin/lesson'); 58 59 60 } 61 62 /** 63 * Display the specified resource. 64 * 65 * @param int $id 66 * @return IlluminateHttpResponse 67 */ 68 public function show($id) 69 { 70 // 71 } 72 73 /** 74 * Show the form for editing the specified resource. 75 * 76 * @param int $id 77 * @return IlluminateHttpResponse 78 */ 79 public function edit($id) 80 { 81 // 82 } 83 84 /** 85 * Update the specified resource in storage. 86 * 87 * @param IlluminateHttpRequest $request 88 * @param int $id 89 * @return IlluminateHttpResponse 90 */ 91 public function update(Request $request, $id) 92 { 93 // 94 } 95 96 /** 97 * Remove the specified resource from storage. 98 * 99 * @param int $id 100 * @return IlluminateHttpResponse 101 */ 102 public function destroy($id) 103 { 104 // 105 } 106 }
44-50行:增加课程数据
53-56行:增加视频数据
第55行:所有通过一操作多的时候,都要用上模型中定义的那个方法:$lesson->videos()->create($video);
3、视图
resources/views/admin/lesson/create.blade.php
1 @extends('admin.layout.master') 2 @section('title','新增课程') 3 @section('content') 4 <!-- Content Header (Page header) --> 5 <section class="content-header"> 6 <h1> 7 Dashboard 8 <small>Control panel</small> 9 </h1> 10 <ol class="breadcrumb"> 11 <li><a href="#"><i class="fa fa-dashboard"></i> Home</a></li> 12 <li class="active">Dashboard</li> 13 </ol> 14 </section> 15 16 <!-- Main content --> 17 <section class="content"> 18 <div style="padding-bottom:15px;"> 19 <div class="btn-group" role="group" aria-label="..."> 20 <a href="/admin/lesson" type="button" class="btn btn-default">课程列表</a> 21 <a href="/admin/lesson/create" type="button" class="btn btn-warning">新增课程</a> 22 </div> 23 </div> 24 25 <div class="box box-info"> 26 <div class="box-header with-border"> 27 <h3 class="box-title">Horizontal Form</h3> 28 </div> 29 <!-- /.box-header --> 30 <!-- form start --> 31 <form class="form-horizontal" action="/admin/lesson" method="post"> 32 {{csrf_field()}} 33 <div class="box-body"> 34 <div class="form-group"> 35 <label for="title" class="col-sm-2 control-label">课程标题</label> 36 37 <div class="col-sm-10"> 38 <input type="text" name="title" class="form-control" id="title" required placeholder="标题"> 39 </div> 40 </div> 41 <div class="form-group"> 42 <label for="introduce" class="col-sm-2 control-label">介绍</label> 43 <div class="col-sm-10"> 44 <textarea name="introduce" class="form-control" id="introduce" rows="5" required></textarea> 45 </div> 46 </div> 47 <div class="form-group"> 48 <label for="preview" class="col-sm-2 control-label">预览图</label> 49 <div class="col-sm-10"> 50 <div class="input-group"> 51 <input type="text" class="form-control" name="preview" readonly="" 52 value="images/nopic.jpg" required> 53 <div class="input-group-btn"> 54 <button onclick="upImage(this)" class="btn btn-default" 55 type="button">选择图片 56 </button> 57 </div> 58 </div> 59 <div class="input-group" style="margin-top:5px;"> 60 <img src="{{asset('images/nopic.jpg')}}" 61 class="img-responsive img-thumbnail" width="150"> 62 <em class="close" style="position:absolute; top: 0px; right: -14px;" 63 title="删除这张图片" onclick="removeImg(this)">×</em> 64 </div> 65 </div> 66 <script> 67 //上传图片 68 function upImage(obj) { 69 require(['util'], function (util) { 70 options = { 71 multiple: false,//是否允许多图上传 72 }; 73 util.image(function (images) { //上传成功的图片,数组类型 74 $("[name='preview']").val(images[0]); 75 $(".img-thumbnail").attr('src', images[0]); 76 }, options) 77 }); 78 } 79 80 //移除图片 81 function removeImg(obj) { 82 $(obj).prev('img').attr('src', 'resource/images/nopic.jpg'); 83 $(obj).parent().prev().find('input').val(''); 84 } 85 </script> 86 </div> 87 <div class="form-group"> 88 <label for="is_commend" class="col-sm-2 control-label">推荐</label> 89 <div class="col-sm-10"> 90 <label class="radio-inline"> 91 <input type="radio" name="is_commend" id="is_commend1" value="1"> 是 92 </label> 93 <label class="radio-inline"> 94 <input type="radio" name="is_commend" id="is_commend0" value="0" checked> 否 95 </label> 96 </div> 97 </div> 98 <div class="form-group"> 99 <label for="is_hot" class="col-sm-2 control-label">热门</label> 100 <div class="col-sm-10"> 101 <label class="radio-inline"> 102 <input type="radio" name="is_hot" id="is_hot1" value="1"> 是 103 </label> 104 <label class="radio-inline"> 105 <input type="radio" name="is_hot" id="is_hot0" value="0" checked> 否 106 </label> 107 </div> 108 </div> 109 <div class="form-group"> 110 <label for="click" class="col-sm-2 control-label">点击数</label> 111 112 <div class="col-sm-10"> 113 <input type="number" name="click" class="form-control" id="click" placeholder="点击数" value="0"> 114 </div> 115 </div> 116 117 {{--视频管理--}} 118 <div class="panel panel-info" id="app"> 119 <div class="panel-heading">视频管理</div> 120 <div class="panel-body"> 121 {{--子元素--}} 122 <div class="panel panel-default" v-for="(v,k) in videos"> 123 <div class="panel-body"> 124 <div class="form-group"> 125 <label for="v_title" class="col-sm-2 control-label">视频标题</label> 126 127 <div class="col-sm-10"> 128 <input type="text" name="v_title" class="form-control" v-model="v.title"> 129 </div> 130 </div> 131 <div class="form-group"> 132 <label for="v_path" class="col-sm-2 control-label">视频地址</label> 133 <div class="col-sm-10"> 134 <input type="text" name="v_path" class="form-control" v-model="v.path"> 135 </div> 136 </div> 137 </div> 138 <div class="panel-footer"> 139 <button class="btn btn-success btn-sm" @click.prevent="del(k)">删除视频</button> 140 </div> 141 </div> 142 {{--END-子元素--}} 143 <div class="form-group"> 144 <textarea name="videos" cols="30" rows="10">@{{videos}}</textarea> 145 </div> 146 </div> 147 <div class="panel-footer"> 148 <button class="btn btn-primary btn-sm" @click.prevent="add">添加视频</button> 149 </div> 150 151 152 </div> 153 154 </div> 155 <!-- /.box-body --> 156 157 <div class="box-footer"> 158 <button type="submit" class="btn btn-info">保存数据</button> 159 </div> 160 <!-- /.box-footer --> 161 </form> 162 </div> 163 164 <script> 165 require(['vue'],function (Vue) { 166 new Vue({ 167 el:'#app', 168 data:{ 169 videos:[{title:'',path:''}] 170 }, 171 methods:{ 172 add:function () { 173 this.videos.push({title:'',path:''}); 174 }, 175 del:function (k) { 176 this.videos.splice(k,1); 177 } 178 } 179 }); 180 }); 181 </script> 182 183 </section> 184 <!-- /.content --> 185 @endsection
第144行:一对多中多的那部分的数据是通过json到服务器的,然后添加到数据库
resources/views/admin/lesson/index.blade.php
1 @extends('admin.layout.master') 2 @section('title','课程页面') 3 @section('content') 4 <!-- Content Header (Page header) --> 5 <section class="content-header"> 6 <h1> 7 Dashboard 8 <small>Control panel</small> 9 </h1> 10 <ol class="breadcrumb"> 11 <li><a href="#"><i class="fa fa-dashboard"></i> Home</a></li> 12 <li class="active">Dashboard</li> 13 </ol> 14 </section> 15 16 <!-- Main content --> 17 <section class="content"> 18 <div style="padding-bottom:15px;"> 19 <div class="btn-group" role="group" aria-label="..."> 20 <a href="/admin/lesson" type="button" class="btn btn-warning">课程列表</a> 21 <a href="/admin/lesson/create" type="button" class="btn btn-default">新增课程</a> 22 </div> 23 </div> 24 25 <div class="box box-primary"> 26 <div class="box-header with-border"> 27 <h3 class="box-title">Bordered Table</h3> 28 </div> 29 <!-- /.box-header --> 30 <div class="box-body"> 31 <div class="table-responsive" style="overflow: visible;min-height: 200px;"> 32 <table class="table table-hover"> 33 <tbody> 34 <tr class="info"> 35 <th style=" 10px">#</th> 36 <th>课程</th> 37 <th>视频数量</th> 38 <th>操作</th> 39 </tr> 40 @foreach($data as $d) 41 <tr> 42 <td>{{$d['id']}}.</td> 43 <td>{{$d['title']}}</td> 44 <td>{{$d->videos()->count()}}</td> 45 <td> 46 <div class="btn-group"> 47 <button type="button" class="btn btn-info">操作</button> 48 <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"> 49 <span class="caret"></span> 50 <span class="sr-only">Toggle Dropdown</span> 51 </button> 52 <ul class="dropdown-menu" role="menu" style=""> 53 <li><a href="/admin/lesson/{{$d['id']}}/edit">编辑</a></li> 54 <li><a href="javascript:;" onclick="del({{$d['id']}})">删除</a></li> 55 </ul> 56 </div> 57 </td> 58 </tr> 59 @endforeach 60 61 </tbody> 62 </table> 63 </div> 64 65 </div> 66 <!-- /.box-body --> 67 <div class="box-footer clearfix"> 68 <ul class="pagination pagination-sm no-margin pull-right"> 69 <li><a href="#">«</a></li> 70 <li><a href="#">1</a></li> 71 <li><a href="#">2</a></li> 72 <li><a href="#">3</a></li> 73 <li><a href="#">»</a></li> 74 </ul> 75 </div> 76 </div> 77 78 </section> 79 <!-- /.content --> 80 <script> 81 function del(id){ 82 // require(['util'],function () { 83 // util.confirm('确定删除么?',function () { 84 // 85 // }); 86 // }); 87 if(confirm('确定删除么')){ 88 $.ajax({ 89 url:'/admin/lesson/'+id, 90 method:'DELETE', 91 success:function (response) { 92 location.reload(); 93 } 94 }); 95 } 96 } 97 </script> 98 @endsection
第44行:直接 {{$d->videos()->count()}}就可以得到课程视频数,毕竟$data获取的只是Lesson模型的数据:$data=Lesson::get();