我用Laravel-目录别名/模型/模型关系

现在是2017年2月5日,从开始接触Laravel也有小一年来了,这篇文章将记录我使用Laravel的一些新得。新的想法也将随时更新到这篇文章中。

1.目录别名

1.1说明

在ShenCom他们有一点做的很好,就是把框架外的扩展全部放在了一个独立的目录里面,没有去破坏Laravel框架本身的结构,让框架保持了原来的特性,又增加了新的功能。

我用Laravel-目录别名/模型/模型关系_第1张图片
1-目录别名.png

1.2用法

1.2.1添加主服务文件

在 app\Providers\AppServiceProvider的boot方法中添加
App::register("\YaZhou\YaZhouServiceProvider");

1.2.2起别名

compser.json里面增加一个autoload选项。
执行命令composer dump-autpload

2.模型(Model)的定义

2.1简单示例

namespace Yz\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Test extends Model{
    use SoftDeletes;

    protected   $primaryKey  =   "id";  
    protected   $table       =   "test";
    protected   $guarded     =   ["id"];
    public      $timestamps  =   false;
}

2.2代码说明

protected $table
指定当前模型对应的数据表名。
protected $primaryKey
指定当前数据表的主键,默认id。
public $timestamps
默认情况下,Eloquent期望created_at和updated_at已经存在于数据表中,如果你不想要这些Laravel自动管理的列,在模型类中设置$timestamps属性为false。
protected $guarded/$fillale
在使用create方法保存一个新的模型时,所有的Eloquent模型都通过批量赋值(Mass Assignment)进行保护,需要指定模型的fillableguarded属性。在fillable里面的都是可以被赋值的(白名单),在guarded里面的都是不可以被赋值的(黑名单),fillable和guarded二选一。
use SoftDeletes
软删除,要求数据表中以一个字段“deleted_at”。被软删除的记录并没有被真正的删除,只是在“deleted_at”字段记录了操作时间。
Model::withTrashed()->...,同时获取被软删除的记录。
Model::onlyTrashed()->...,只获取被软删除的记录。
$record->restore();,恢复被软删除的记录。
$record->forceDelete(),强制删除。
$record-> history() -> forceDelete(),强制删除所有关模型。

2.3扩展

查询作用域

作用域允许你定义一个查询条件的通用集合,这样就可以在应用中方便地复用。详情参见,Laravel5.1中文文档。

3.模型关系

3.1一对一关系

3.1.1关系的定义
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model{
    //  获取关联到用户的手机
    public function phone(){
        return $this->hasOne("Yz\Test\Models\Phone");
        // 这种写法默认Phone模型中有一个user_id外键,默认与当前模型的id关联

        // return $this->hasOne("Yz\Test\Models\Phone", "user_id");
        // 指定Phone模型中的外键,默认与当前模型的id关联
        
        // return $this->hasOne("Yz\Test\Models\Phone", "user_id", "id");
        // 指定phone模型的外键,同时指定当前模型的关联键,推荐使用
    }
}
3.1.2定义关系的相对关联
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class Phone extends Model{
    public function user(){
        // 找到电话所属的用户
        return $this->belongsTo("Yz\Test\Models\User");
        // 默认通过当前表的user_id去匹配user表的id

        // return $this->belongsTo("Yz\Test\Models\User", "user_id");
        // 指定当前表的关联字段,去与主表的id字段进行匹配
        
        // return $this->belongsTo("Yz\Test\Models\User", "user_id", "id");
        // 指定当前表的user_id与User表的id进行匹配,推荐使用
    }
}
3.1.3一对一关系的使用

$phone = User::find(1)->phone;

3.2 一对多关系

3.2.1关系的定义
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model{
    /*博客数据*/

    public function comments(){
        // 获取博客的评论
        return $this->hasMany("Yz\Test\Models\Comment");

        // $this->hasMany("Yz\Test\Models\Comment", "post_id");
        // $this->hasMany("Yz\Test\Models\Comment", "post_id", "id");
    }
}
3.2.2定义关系的相对关联
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model{
    /*博客的评论*/

    public function post(){
        return $this->belongsTo("Yz\Test\Models\Post");

        // return $this->belongsTo("Yz\Test\Models\Post", "post_id");
        // return $this->belongsTo("Yz\Test\Models\Post", "post_id", "id");
    }
}
3.2.3一对多关系的使用
$comments = App\Post::find(1)->comments;
$comments = App\Post::find(1)->comments()->where('title', 'foo')->first();

$comment = App\Comment::find(1);
echo $comment->post->title;

3.3多对多关系

实现多对多关系需要一个中间表。比如,一个用户(user)拥有多种角色(role),那么我们就需要一个中间表(user_role)。

3.3.1关系的定义
public function roles(){
        return $this->belongsToMany("Yz\Test\Model\Role");
        // 省略写法,要求中间表的名字为role_user,且中间表包含role_id和user_id两个字段
        
        // return $this->belongsToMany("Yz\Test\Models\Role", "user_role");
        // 半完整写法
        
        // return $this->belongsToMany("Yz\Test\Models\Role", "user_role", "user_id", "role_id");
        // 完整写法
    }
3.3.2定义关系的相对关联
namespace Yz\Test\Models;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    // 用户角色

    public function users()
    {
        // 找到属于当前角色的用户
        return $this->belongsToMany("Yz\Test\Models\User");

        // return $this->belongsToMany("Yz\Test\Models\User", "user_role");
        // return $this->belongsToMany("Yz\Test\Models\User", "user_role", "role_id", "user_id");
    }
}
3.3.3多对多关系的使用
$user = App\User::find(1);
foreach ($user->roles as $role) {
    //
}

$roles = App\User::find(1)->roles()->orderBy('name')->get();

3.4插入关联模型

3.4.1插入一个关联模型
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
$comment = $post->comments()->save($comment);
3.4.2插入多个关联模型
$post = App\Post::find(1);
$post->comments()->saveMany([
    new App\Comment(['message' => 'A new comment.']),
    new App\Comment(['message' => 'Another comment.']),
]);

除了save和saveMany方法外,还可以使用create方法,该方法接收属性数组、创建模型、然后插入数据库。save和create的不同之处在于save接收整个Eloquent模型实例而create接收原生PHP数组。

$post = App\Post::find(1);
$comment = $post->comments()->create([
    'message' => 'A new comment.',
]);
3.4.3更新关联模型

更新belongsTo关联的时候,可以使用associate方法,该方法会在子模型设置外键。

$account = App\Account::find(10);
$user->account()->associate($account);
$user->save();
3.4.4移除关联模型

移除belongsTo关联的时候,可以使用dissociate方法。该方法在子模型上取消外键和关联。

$user->account()->dissociate();
$user->save();
3.4.5多对多关系的附加
$user = App\User::find(1);
$user->roles()->attach($roleId);

附加关联关系到模型,还可以以数组形式传递额外被插入数据到中间表:
$user->roles()->attach($roleId, ['expires' => $expires])

3.4.6多对多关系的移除
// 从指定用户中移除角色...
$user->roles()->detach($roleId);
// 从指定用户移除所有角色...
$user->roles()->detach();

为了方便,attach和detach还接收数组形式的ID作为输入。

$user = App\User::find(1);
$user->roles()->detach([1, 2, 3]);
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
3.4.7触发父级时间戳

当一个模型属于另外一个时,例如Comment属于Post,子模型更新时父模型的时间戳也被更新将很有用,例如,当Comment模型被更新时,你可能想要”触发“创建其所属模型Post的updated_at时间戳。Eloquent使得这项操作变得简单,只需要添加包含关联关系名称的touches属性到子模型中即可。

你可能感兴趣的:(我用Laravel-目录别名/模型/模型关系)