欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Eloquent ORM 实例教程 —— 模型创建、更新及批量赋值

shiping1 的头像

1、创建模型

1.1 使用save方法创建模型

调用Eloquent模型类的save方法即可创建模型并插入数据到数据库:

$post = new Post;
$post->title = 'test 4';
$post->content = 'test content';
$post->user_id = 1;
$post->cat_id = 1;
if($post->save()){
    echo '添加文章成功!';
}else{
    echo '添加文章失败!';
}

在浏览器中访问http://laravel.app:8000/test,如果输出内容为:

添加文章成功!

则表明插入成功,我们去数据库查看数据,确实新增了一条记录:

使用save创建模型

1.2 使用create方法插入数据

除此之外还可以使用create方法插入数据,由于该方法中用到了批量赋值(Mass Assignment),所以我们需要在模型类中设置$fillable属性或者$guarded属性,以表明哪些属性可以通过该方法设置,哪些不可以。

开始之前,我们先解释下什么是批量赋值,以及为什么要使用批量赋值

批量赋值的英文名称是Mass Assignment,所谓的批量赋值是指当我们将一个数组发送到模型类用于创建新的模型实例的时候(通常是表单请求数据),我们可以简单通过如下方式实现:

$post = Post::create(Input::all());

而不是像使用save方法那样一个一个的设置属性值,如果模型属性很多的话,使用save简直是噩梦有木有。

但事物总是相对的,使用批量赋值是很方便,但同时也带来了安全隐患,很多时候模型类的某些属性值不是我们所期望通过批量赋值修改的,比如用户模型有个user_type属性,如果用户通过请求数据将其类型修改为管理员类型,这显然是不允许的,正是基于这一考虑,Eloquent模型类为我们提供了$fillable属性和$guarded属性,我们可以将其分别看作“白名单”和“黑名单”,定义在$fillable中的属性可以通过批量赋值进行赋值,而定义在$guarded中的属性在批量赋值时会被过滤掉。

那么如果我们确实想要修改定义在$guarded中的属性怎么办?答案是使用save方法。

此外需要注意的是$fillable$guarded方法同时只能定义一个,原因嘛很简单,非黑即白,定义了一个另外一个也就确定了。

可见批量赋值不仅为我们创建模型提供了便利,还避免了安全隐患,提高了系统的安全性。

下面我们来演示一下批量赋值的使用。首先在Post模型中定义$guarded属性如下:

protected $guarded = ['views','user_id','updated_at','created_at'];

然后在控制器中实现创建模型实例的逻辑:

$input = [
    'title'=>'test 5',
    'content'=>'test content',
    'cat_id'=>1,
    'views'=>100,
    'user_id'=>2
];
$post = Post::create($input);
dd($post);

在浏览器中输入http://laravel.app:8000/test,则页面输出:

使用批量赋值创建模型

可见user_idviews字段都没有插入进去,这正是$guarded发挥了作用,如果要设置这两个值也很简单:

$input = [
    'title'=>'test 5',
    'content'=>'test content',
    'cat_id'=>1,
    'views'=>100,
    'user_id'=>2
];
$post = Post::create($input);
$post->user_id = 2;
$post->views = 100;
$post->save();
dd($post);

对应输出如下:

使用save方法保存$guarded数据

1.3 其他插入数据的方法

Eloquent模型类还支持其它插入数据的方法——firstOrCreatefirstOrNew,两者都是先通过通过传入属性值在数据库中查找匹配记录,如果没有找到则创建一个新的模型实例,不同之处在于后者不会将数据持久化到数据库,需要调用save方法才行。

2、更新模型

2.1 使用save方法更新模型

save方法还可以用于更新模型,要更新模型数据,先要获取该模型实例,然后修改模型属性,再调用save方法保存即可:

$post = Post::find(1);
$post->title = 'test 1 title';
if($post->save()){
    echo '更新文章成功!';
}else{
    echo '更新文章失败!';
}

在浏览器中访问http://laravel.app:8000/test,如果显示:

更新文章成功!

则表明数据库对应表记录更新成功:

使用update方法更新模型

2.2 使用update方法更新数据

create相对应的,Eloquent模型类还支持使用update方法更新数据,同样要用到批量赋值:

$input = [
    'title'=>'test 6 title',
    'content'=>'test content 6',
    'cat_id'=>1,
    'views'=>200,
    'user_id'=>1
];
$post = Post::find(6);
if($post->update($input)){
    echo '更新文章成功!';
    dd($post);
}else{
    echo '更新文章失败!';
}

对应输出为:

使用update更新模型

可见user_idviews并没有更新。

  • 乐仔共享
    1. 袁源
      页面显示更新成功,但数据库中并未成功       

    我的也是

  • 袁源

    页面显示更新成功,但数据库中并未成功

  • 学院君
    1. 仰望丶訫愠
      仰望丶訫愠4月7日
      1楼
      更新模型的方法只能用find吗,可以用where吗,如果我比对的值不是主键怎么处理?       

    当然可以啊 只要获取的是对应实例即可

  • 仰望丶訫愠
    仰望丶訫愠

    更新模型的方法只能用find吗,可以用where吗,如果我比对的值不是主键怎么处理?

  • 学院君
    1. 星空
      学员君,能只生成模型但不进行插入数据库操作吗?       

    只new 不要执行save或insert方法?

  • 星空

    学员君,能只生成模型但不进行插入数据库操作吗?

  • 学院君
    1. @yangwenqian
      请问学院君,我用$input=Input::all();Post::create($input);出错,因为Input::all()里面有个_token,但我数据库中没有这个字段,我想把$input中的_token删除,再create,该怎么写?谢谢       

    使用Input::except('_token')排除

  • @yangwenqian

    请问学院君,我用$input=Input::all();Post::create($input);出错,因为Input::all()里面有个_token,但我数据库中没有这个字段,我想把$input中的_token删除,再create,该怎么写?谢谢

  • 学院君
    1. 阿布力米提
      我想更新数据 一定两次操作数据库么
      先find()后update或save()么? 能不能一次性更新?;
      用update($data) $data里面有id会报错,根据id更新不久行了么?       

    试下updateOrCreate这个方法

  • 阿布力米提

    我想更新数据 一定两次操作数据库么
    先find()后update或save()么? 能不能一次性更新?;
    用update($data) $data里面有id会报错,根据id更新不久行了么?


来自  http://laravelacademy.org/post/984.html
普通分类: