Larevel Отношение из массива в базе данных - PullRequest
0 голосов
/ 04 февраля 2020

Мне было интересно, могли бы вы помочь с 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'],
]);

Поле условий «условия» хранит массив следующим образом:

[{"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 документах.

Ответы [ 3 ]

1 голос
/ 04 февраля 2020

вы не можете получить условие с отношением, вам нужно сделать так:

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

, и оно будет динамически получаться с вашими данными, и это будет похоже на logi c

0 голосов
/ 05 февраля 2020

Почему вы не моделируете отношения между многими оповещениями и условиями, как многие ко многим?

Я бы использовал следующие миграции:

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'));
0 голосов
/ 04 февраля 2020

Модель оповещений

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 и пользователя идентификатор с несколькими условиями, такими как:

user_id: 1 условие: 1

user_id: 1 условие: 2

user_id: 1 условие: 3

...