美文网首页
3分钟短文:说说Laravel模型中还算常用的2个“关系”

3分钟短文:说说Laravel模型中还算常用的2个“关系”

作者: 程序员小助手 | 来源:发表于2020-10-19 21:25 被阅读0次

    引言

    上一章我们介绍了比较简单的laravel模型关联关系中的一对一,介绍了关联操作方法。
    太难的概念理解起来都费劲,更不用说写代码了,所以对于太难的那些关联关系,
    且不论其效率如何,我们都不先做介绍。

    img

    本期说一说2个比较常用的关联模型。

    belongsTo 关系

    正好像对于一个词语,找到对应的反义词,或者说有一个图片,找到其镜像图片这样的。
    有作用力,就有反作用力。一对一关系模型中,A有一个B,则反过来,B属于一个A。
    这就是首先要介绍的 belongsTo 关系。

    在模型Profile中添加对应到User模型的关系:

    class Profile extends Model {
        public function user()
        {
            return $this->belongsTo('App\User');
        }
    }
    

    也就是说,有一个profile是从属于user的,这与User模型的hasOne正好是对应关系。
    在代码中使用该关联关系:

    $email = Profile::where('id', 3)->first()->user->email;
    

    其中first方法返回一个Profile模型对象实例,在Profile类中我们声明了 user() 方法用于关系用户模型,
    所以此处链式调用 user 属性,返回的是一个 App\User 对象实例,其包含 User 模型的所有属性,
    因此 email 属性也相应返回数据库内的字段值。

    一对多关系

    还有一个常见的关联关系是一对多。比如一个用户有多个手机号,一种状态包含很多个事件,一个商品有多个标签等等等等,
    这都是一对多的常见用法。

    我们使用State模型状态有多个Event事件这个场景,演示一下一对多关系的声明,以及应用。在命令行创建模型文件,同时创建迁移文件:

    php artisan make:model State --migration
    

    默认在 App\State.php 文件内生成下面的代码:

    use Illuminate\Database\Eloquent\Model;
    class State extends Model {}
    

    我们还是先去生成数据库表的迁移文件,手动实现迁移字段:

    public function up()
    {
        Schema::create('states', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('name');
            $table->string('abbreviation');
            $table->timestamps();
        });
    }
    

    以及撤回迁移时删除表:

    public function down()
    {
        Schema::drop('states');
    }
    

    接着在命令行执行迁移指令:

    php artisan migrate
    

    执行成功,数据库表states就创建成功了。

    我们说关联关系需要外键,所以需要手动在events表内追加一个字段 state_id,用于指向刚才创建的表states的id字段。
    执行命令行,创建迁移文件:

    php artisan make:migration add_state_id_to_events_table --table=events
    

    手动实现迁移文件的修改:

    public function up()
    {
        Schema::table('events', function (Blueprint $table) {
            $table->integer('state_id')->unsigned()->nullable();
            $table->foreign('state_id')->references('id')->on('states');
        });
    }
    

    以及回滚迁移时手动删除追加的字段:

    public function down()
    {
        Schema::table('events', function (Blueprint $table) {
            $table->dropForeign('events_state_id_foreign');
            $table->dropColumn('state_id');
        });
    }
    

    基础数据准备完毕,下面在模型内添加关联关系:

    class State extends Model {
        public function events() {
            return $this->hasMany('App\Event');
        }
    }
    

    非常直观,一种状态,有若干个事件。反过来,一个事件,一定属于某种状态,那就是belongsTo关系。

    class Event extends Model {
        public function state()
        {
            return $this->belongsTo('App\State');
        }
    }
    

    代码层面也准备好了,下面可以开始使用了。比如创建事件时,手动为其指定状态:

    $event = new Event;
    $event->name = "Laravel Hacking and Pizza";
    $event->state_id = 41;
    $event->save();
    

    注意,hasMany关联关系,返回的是多个模型的集合,可以后续链式调用集合的所有方法。

    写在最后

    本文不失简单地介绍了belongsTo和hasMany两个关联关系,这在代码中仅次于hasOne关系,
    使用的频次比较高的。而效率也就是根据外键多查询一次SQL的消耗而已。但是明白其中原理之后,
    在代码内耗时的操作里,也绝不可滥用关联关系,否则会严重消耗性能。

    Happy coding :-)

    我是@程序员小助手,专注编程知识,圈子动态的IT领域原创作者

    相关文章

      网友评论

          本文标题:3分钟短文:说说Laravel模型中还算常用的2个“关系”

          本文链接:https://www.haomeiwen.com/subject/nketmktx.html