【问题标题】:Laravel Relationship from array in database来自数据库中数组的 Laravel 关系
【发布时间】:2020-05-20 05:52:30
【问题描述】:

我想知道你是否可以帮助建立 laravel 关系。我会尽力解释。

我有两张桌子:

警报

Schema::create('alerts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id');
            $table->float('price_low')->nullable();
            $table->float('price_high')->nullable();
            $table->json('conditions')->nullable();
            $table->softDeletes();
            $table->timestamps();
        });

条件

DB::table('conditions')->insert([
            ['condition_value' => 'New'],
            ['condition_value' => 'Second Hand'],
            ['condition_value' => 'Ex Demo'],
]);

条件字段'conditions'存储一个这样的数组:

[{"condition_id": 1}, {"condition_id": 2}]

我正在尝试定义一种关系,以便可以执行以下操作:

$alerts = Alerts::with(['condition'])->where('user_id', $request->user()->id)->get();

我的警报模型如下所示:

<?php

namespace App;

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

class Alerts extends Model
{
    protected $casts = [
        'conditions' => 'array'
    ];
    

    public function user(){
        return $this->hasOne('App\User', 'id', 'user_id');
    }

    public function condition(){
        return $this->hasMany('App\Condition', 'id', 'conditions[condition_id]');
    }
}

但没有返回任何内容,我正在努力在 Laravel 文档中找到答案。

【问题讨论】:

    标签: laravel laravel-5 eloquent eloquent-relationship


    【解决方案1】:

    警报模型

    Schema::create('alerts', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->integer('user_id');
                $table->float('price_low')->nullable();
                $table->float('price_high')->nullable();
                $table->unsignedBigInteger('conditions')->nullable();
                $table->foreign('conditions')->references('id')->on('conditions');
                $table->softDeletes();
                $table->timestamps();
            });
    

    条件模型

    Schema::create('conditions', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('condition_value')->nullable();
                $table->softDeletes();
                $table->timestamps();
            });
    

    在警报表中为一个 user_id 插入多个记录,例如一个用户 ID 具有多个条件,例如:

    user_id: 1 条件:1

    user_id: 1 条件:2

    user_id: 1 条件:3

    【讨论】:

    • 您会将数组存储在警报表中的什么位置?
    • 如果表之间有关系为什么要存储数组?在该表中保存多条记录。这将适用于您现有的关系查询。 user_id: 1 condition: 1 user_id: 1 condition: 2 user_id: 1 condition: 3 这只是将其保存在表中的指示。
    【解决方案2】:

    你无法得到你需要的关系的条件

    public function getConditionsAttribute($conditions)
        {
            return App\Condition::whereIn('id',collect($conditions)->pluck('condition_id'))->get();
        }
    

    它会动态获取你的数据,这将使它像逻辑一样

    【讨论】:

    • 这是一个很好的答案,但需要详细说明以使其真正好。
    【解决方案3】:

    为什么不将警报和条件之间的关系建模为多对多?

    我会使用以下迁移:

    Schema::create('alerts', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedBigInteger('user_id'); // I assume your users table uses a bigIncrements for id
        $table->decimal('price_low')->nullable(); // Do not use FLOAT type for prices as is can cause rounding issues.
        $table->decimal('price_high')->nullable();
        $table->softDeletes();
        $table->timestamps();
    
        $table->foreign('user_id')->references('id')->on('users');
    });
    
    Schema::create('alert_condition', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->unsignedBigInteger('alert_id');
        $table->unsignedBigInteger('condition_id');
        $table->timestamps();
    
        $table->foreign('alert_id')->references('id')->on('alerts');
        $table->foreign('condition_id')->references('id')->on('conditions');
    });
    
    Schema::create('conditions', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('value');
        $table->timestamps();
    });
    

    插入您现在必须使用的条件:

    DB::table('conditions')->insert([
        ['value' => 'New'],
        ['value' => 'Second Hand'],
        ['value' => 'Ex Demo'],
    ]);
    

    您需要注意的唯一额外事项是,警报和条件之间的每个关联都将是 alert_condition 数据透视表中的一条记录,其中包含您要连接的两个模型的外键。

    这可以通过多种方式完成。要坚持以前的 conditions 插入,您可以使用:

    DB::table('alert_condition')->insert([
        ['alert_id' => 1, 'condition_id' => 1],
        ['alert_id' => 1, 'condition_id' => 2],
        ['alert_id' => 2, 'condition_id' => 1],
        // ...
    ]);
    

    然后我会使用以下模型:

    警报模型

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Relations\Pivot;
    use Illuminate\Database\Eloquent\SoftDeletes;
    
    class Alerts extends Pivot
    {
        use SoftDeletes;
    
        public function user()
        {
            return $this->belongsTo(User::class);
        }
    
        public function conditions()
        {
            return $this->belongsToMany(Condition::class);
        }
    }
    

    条件模型

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Condition extends Model
    {
        public function alerts()
        {
            return $this->belongsToMany(Alert::class);
        }
    }
    

    然后在你的控制器或任何你需要的地方你可以像这样查询:

    // Assuming your authentication works with the User model and that model
    // has a correct hasMany alerts() relationship.
    $user = Auth::user();
    
    // This would print out all the alerts for the current logged in user
    // and each alert will contain the conditions values associated to that alert.
    dump($user->alerts()->with('conditions')->get());
    
    // If you also need to keep the user with its data, just eager load the relations
    dump($user->load('alerts.conditions'));
    

    【讨论】:

      猜你喜欢
      • 2014-10-30
      • 1970-01-01
      • 2016-01-05
      • 2020-05-11
      • 2015-02-07
      • 2021-02-08
      • 1970-01-01
      相关资源
      最近更新 更多