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

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

1.目录别名

1.1说明

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

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属性到子模型中即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容