后盾网lavarel视频项目---lavarel多表关联一对多操作实例
后盾网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
<?php namespace App\Model; use Illuminate\Database\Eloquent\Model; class Lesson extends Model
{
/**
* 与视频表模型的一对多关联
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function videos(){
return $this->hasMany(Video::class);
}
}
app/Model/Video.php
<?php namespace App\Model; use Illuminate\Database\Eloquent\Model; class Video extends Model
{
protected $guarded=[];
}
2、控制器
app/Http/Controllers/Admin/LessonController.php
<?php namespace App\Http\Controllers\Admin; use App\Model\Lesson;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller; class LessonController extends CommonController
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$data=Lesson::get();
//dd($data->toArray());
return view('admin.lesson.index',compact('data'));
} /**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
// $d=Lesson::find(1)->videos()->get();
// dd($d->toArray());
return view('admin.lesson.create');
} /**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request,Lesson $lesson)
{
//dd($request->toArray());
$lesson['title']=$request['title'];
$lesson['introduce']=$request['introduce'];
$lesson['preview']=$request['preview'];
$lesson['is_commend']=$request['is_commend'];
$lesson['is_hot']=$request['is_hot'];
$lesson['click']=$request['click'];
$lesson->save(); //videos数据过来的时候是json数据,true表示转成数组而非对象
$videos=json_decode($request['videos'],true);
foreach ($videos as $video){
$lesson->videos()->create($video);
}
return redirect('/admin/lesson'); } /**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
} /**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
} /**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
} /**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
44-50行:增加课程数据
53-56行:增加视频数据
第55行:所有通过一操作多的时候,都要用上模型中定义的那个方法:$lesson->videos()->create($video);
3、视图
resources/views/admin/lesson/create.blade.php
@extends('admin.layout.master')
@section('title','新增课程')
@section('content')
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Dashboard
<small>Control panel</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Home</a></li>
<li class="active">Dashboard</li>
</ol>
</section> <!-- Main content -->
<section class="content">
<div style="padding-bottom:15px;">
<div class="btn-group" role="group" aria-label="...">
<a href="/admin/lesson" type="button" class="btn btn-default">课程列表</a>
<a href="/admin/lesson/create" type="button" class="btn btn-warning">新增课程</a>
</div>
</div> <div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">Horizontal Form</h3>
</div>
<!-- /.box-header -->
<!-- form start -->
<form class="form-horizontal" action="/admin/lesson" method="post">
{{csrf_field()}}
<div class="box-body">
<div class="form-group">
<label for="title" class="col-sm-2 control-label">课程标题</label> <div class="col-sm-10">
<input type="text" name="title" class="form-control" id="title" required placeholder="标题">
</div>
</div>
<div class="form-group">
<label for="introduce" class="col-sm-2 control-label">介绍</label>
<div class="col-sm-10">
<textarea name="introduce" class="form-control" id="introduce" rows="5" required></textarea>
</div>
</div>
<div class="form-group">
<label for="preview" class="col-sm-2 control-label">预览图</label>
<div class="col-sm-10">
<div class="input-group">
<input type="text" class="form-control" name="preview" readonly=""
value="images/nopic.jpg" required>
<div class="input-group-btn">
<button onclick="upImage(this)" class="btn btn-default"
type="button">选择图片
</button>
</div>
</div>
<div class="input-group" style="margin-top:5px;">
<img src="{{asset('images/nopic.jpg')}}"
class="img-responsive img-thumbnail" width="150">
<em class="close" style="position:absolute; top: 0px; right: -14px;"
title="删除这张图片" onclick="removeImg(this)">×</em>
</div>
</div>
<script>
//上传图片
function upImage(obj) {
require(['util'], function (util) {
options = {
multiple: false,//是否允许多图上传
};
util.image(function (images) { //上传成功的图片,数组类型
$("[name='preview']").val(images[0]);
$(".img-thumbnail").attr('src', images[0]);
}, options)
});
} //移除图片
function removeImg(obj) {
$(obj).prev('img').attr('src', 'resource/images/nopic.jpg');
$(obj).parent().prev().find('input').val('');
}
</script>
</div>
<div class="form-group">
<label for="is_commend" class="col-sm-2 control-label">推荐</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="is_commend" id="is_commend1" value="1"> 是
</label>
<label class="radio-inline">
<input type="radio" name="is_commend" id="is_commend0" value="0" checked> 否
</label>
</div>
</div>
<div class="form-group">
<label for="is_hot" class="col-sm-2 control-label">热门</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="is_hot" id="is_hot1" value="1"> 是
</label>
<label class="radio-inline">
<input type="radio" name="is_hot" id="is_hot0" value="0" checked> 否
</label>
</div>
</div>
<div class="form-group">
<label for="click" class="col-sm-2 control-label">点击数</label> <div class="col-sm-10">
<input type="number" name="click" class="form-control" id="click" placeholder="点击数" value="0">
</div>
</div> {{--视频管理--}}
<div class="panel panel-info" id="app">
<div class="panel-heading">视频管理</div>
<div class="panel-body">
{{--子元素--}}
<div class="panel panel-default" v-for="(v,k) in videos">
<div class="panel-body">
<div class="form-group">
<label for="v_title" class="col-sm-2 control-label">视频标题</label> <div class="col-sm-10">
<input type="text" name="v_title" class="form-control" v-model="v.title">
</div>
</div>
<div class="form-group">
<label for="v_path" class="col-sm-2 control-label">视频地址</label>
<div class="col-sm-10">
<input type="text" name="v_path" class="form-control" v-model="v.path">
</div>
</div>
</div>
<div class="panel-footer">
<button class="btn btn-success btn-sm" @click.prevent="del(k)">删除视频</button>
</div>
</div>
{{--END-子元素--}}
<div class="form-group">
<textarea name="videos" cols="30" rows="10">@{{videos}}</textarea>
</div>
</div>
<div class="panel-footer">
<button class="btn btn-primary btn-sm" @click.prevent="add">添加视频</button>
</div> </div> </div>
<!-- /.box-body --> <div class="box-footer">
<button type="submit" class="btn btn-info">保存数据</button>
</div>
<!-- /.box-footer -->
</form>
</div> <script>
require(['vue'],function (Vue) {
new Vue({
el:'#app',
data:{
videos:[{title:'',path:''}]
},
methods:{
add:function () {
this.videos.push({title:'',path:''});
},
del:function (k) {
this.videos.splice(k,1);
}
}
});
});
</script> </section>
<!-- /.content -->
@endsection
第144行:一对多中多的那部分的数据是通过json到服务器的,然后添加到数据库
resources/views/admin/lesson/index.blade.php
@extends('admin.layout.master')
@section('title','课程页面')
@section('content')
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Dashboard
<small>Control panel</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Home</a></li>
<li class="active">Dashboard</li>
</ol>
</section> <!-- Main content -->
<section class="content">
<div style="padding-bottom:15px;">
<div class="btn-group" role="group" aria-label="...">
<a href="/admin/lesson" type="button" class="btn btn-warning">课程列表</a>
<a href="/admin/lesson/create" type="button" class="btn btn-default">新增课程</a>
</div>
</div> <div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Bordered Table</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<div class="table-responsive" style="overflow: visible;min-height: 200px;">
<table class="table table-hover">
<tbody>
<tr class="info">
<th style="width: 10px">#</th>
<th>课程</th>
<th>视频数量</th>
<th>操作</th>
</tr>
@foreach($data as $d)
<tr>
<td>{{$d['id']}}.</td>
<td>{{$d['title']}}</td>
<td>{{$d->videos()->count()}}</td>
<td>
<div class="btn-group">
<button type="button" class="btn btn-info">操作</button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu" style="">
<li><a href="/admin/lesson/{{$d['id']}}/edit">编辑</a></li>
<li><a href="javascript:;" onclick="del({{$d['id']}})">删除</a></li>
</ul>
</div>
</td>
</tr>
@endforeach </tbody>
</table>
</div> </div>
<!-- /.box-body -->
<div class="box-footer clearfix">
<ul class="pagination pagination-sm no-margin pull-right">
<li><a href="#">«</a></li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">»</a></li>
</ul>
</div>
</div> </section>
<!-- /.content -->
<script>
function del(id){
// require(['util'],function () {
// util.confirm('确定删除么?',function () {
//
// });
// });
if(confirm('确定删除么')){
$.ajax({
url:'/admin/lesson/'+id,
method:'DELETE',
success:function (response) {
location.reload();
}
});
}
}
</script>
@endsection
第44行:直接 {{$d->videos()->count()}}就可以得到课程视频数,毕竟$data获取的只是Lesson模型的数据:$data=Lesson::get();
后盾网lavarel视频项目---lavarel多表关联一对多操作实例的更多相关文章
- 后盾网lavarel视频项目---lavarel中的tinker是什么
后盾网lavarel视频项目---lavarel中的tinker是什么 一.总结 一句话总结: 是用来调试laravel,可以打印变量或对象信息,显示函数代码,对数据库写入和查询数据 laravel中 ...
- 后盾网lavarel视频项目---lavarel用户认证实例
后盾网lavarel视频项目---lavarel用户认证实例 一.总结 一句话总结: 主要是用的Auth认证,所以配置是配置的auth(config/auth.php),控制器中调用也是用的Auth( ...
- 后盾网lavarel视频项目---lavarel使用模型进行增删改查操作
后盾网lavarel视频项目---lavarel使用模型进行增删改查操作 一.总结 一句话总结: 使用模型操作常用方法 查一条:$model=Tag::find($id); 删一条:Tag::dest ...
- 后盾网lavarel视频项目---lavarel中间件(使用中间件拦截没登录的用户)
后盾网lavarel视频项目---lavarel中间件(使用中间件拦截没登录的用户) 一.总结 一句话总结: 1.中间件中验证用户是否登录:if(!Auth::guard('admin')->c ...
- 后盾网lavarel视频项目---4、lavarel和vue都是{{}}表示变量,如何解决冲突
后盾网lavarel视频项目---4.lavarel和vue都是{{}}表示变量,如何解决冲突 一.总结 一句话总结: @{{videos}}:@符号表示lavarel不处理:textarea nam ...
- 后盾网lavarel视频项目---模型一对多关联简单实例
后盾网lavarel视频项目---模型一对多关联简单实例 一.总结 一句话总结: 在模型中定义一个方法来设置一对多关联:return $this->hasMany(Video::class); ...
- 后盾网lavarel视频项目---3、lavarel中子控制器继承父控制器以判断是否登录
后盾网lavarel视频项目---3.lavarel中子控制器继承父控制器以判断是否登录 一.总结 一句话总结: 在common控制器的构造方法中验证登录中间件,其它的控制器继承common控制器 p ...
- 后盾网lavarel视频项目---2、phpstorm显示类中的方法快捷键
后盾网lavarel视频项目---2.phpstorm显示类中的方法快捷键 一.总结 一句话总结: ctrl + f12 1.npm安装js插件? npm install hdjs 2.phpstor ...
- 后盾网lavarel视频项目---1、数据迁移
后盾网lavarel视频项目---1.数据迁移 一.总结 一句话总结: 1.lavarel的数据迁移比较简单,就是用php来创建数据表 2.创建迁移文件:php artisan make:migrat ...
随机推荐
- O006、CPU和内存虚拟化原理
参考https://www.cnblogs.com/CloudMan6/p/5263981.html 前面我们成功的把KVM跑起来了,有了些感性认识,这个对于初学者非常重要.不过还不够,我们多少要 ...
- Linux课程学习 第三课
生活中的许多事,并不是我们不能做到,而是我们不相信能够做到 https://www.linuxcool.com/ 一个很实用的Linux命令查询网站,并且还有发音 如果我们在系统终端中执行一个命令后想 ...
- 欧拉函数 || [SDOI2008]仪仗队 || BZOJ 2190 || Luogu P2158
题面:P2158 [SDOI2008]仪仗队 题解: 显然除了(1,1),(0,1),(1,0)三个点外,对于其他点(x,y)只要满足gcd(x,y)==1就可以被看到 然后这些点是关于y=x对称的, ...
- glViewport函数用法
一. 其函数原型为glViewport(GLint x,GLint y,GLsizei width,GLsizei height) x,y 以像素为单位,指定了窗口的左下角位置. width,heig ...
- mysql5.6新功能索引条件下推(转载)
原文地址:http://www.cnblogs.com/zengkefu/p/5684101.html 一什么是"索引条件下推" "索引条件下推",称为 Ind ...
- MySQL第二次安装随笔
找到之前的MySQL的安装包,重新安装MySQL. 1.设置环境变量,win10的可以右键此电脑-属性,在系统变量Path中添加mysql文件bin的路径 2.修改配置文件mydefault.ini( ...
- Mybatis运用到的3种设计模式
Mybatis运用到的3种设计模式 1.构造者模式2.工厂模式3.代理模式1.构造者模式 使用SqlSessionFactoryBuilder,根据核心配置文件,构造一个SqlSessionFacto ...
- beanFactory & FactoryBean区别
FactoryBean Spring内部实现的一种规范& 开头作为beanName Spring中所有的容器都是FactoryBean 因为容器本身也由容器管理, root来创建 都是单列在I ...
- STM32CUBE+KEIL+Compiler V6使用方法
可以参考:https://blog.csdn.net/PeterSun01/article/details/90445439https://www.jianshu.com/p/18a58fee94ce ...
- entity framework delete table Error 11007:
udate model from database 数据库表删除时,会出现“Error 11007:”的异常,此时在.edmx文件中找到此表的实体发现还存在,删除它就没有这个错误 了.