Один и тот же ключ Foreing дважды, который относится к одной модели - PullRequest
0 голосов
/ 22 мая 2019

Мне нужно сделать платформу для рекомендаций по продуктам. Пользователь может давать советы в разделе продукта. Таким образом, продукт имеет много советов. Также советы принадлежат продукту. Но в таблице product_advices у меня есть product_id и product_advice_id , оба они относятся к идентификатору в таблице продуктов. Так вот в чем проблема. Я могу взять советы из таблицы product_advices, которая ссылается на product_id. Но как я могу взять другой в качестве продукта.

product->advices to show advice and user message
each advices as advice and advice->product->name to show adviced product name

Я не мог установить с ними красноречивых отношений.

//Product Model
public function advices()
{
    return $this->hasMany('App\ProductAdvice', 'product_id');
}

//ProductAdvice Model
protected $table = 'product_advices';

public function product() {
    return $this->belongsTo('App\Product', 'product_id');
}

//Product Advice Table
Schema::create('product_advices', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->unsigned();
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        $table->text('body')->nullable();
        $table->integer('product_id')->unsigned();
        $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
        $table->integer('product_advice_id')->unsigned();
        $table->foreign('product_advice_id')->references('id')->on('products')->onDelete('cascade');
        $table->timestamps();
    });

Например: Iphone имеет много советов пользователей. Iphone-> советы приносит советы из product_advices о том, что Iphone принадлежит столбцу product_id. Когда пользователь рекомендует Samsung Galaxy S10 для Iphone. Samsung ссылается на столбец product_advice_id в таблице product_advices. Но как показать Samsung Galaxy S10 как продукт. $ advice-> product-> name возвращает Iphone вместо Samsung Galaxy S10.

Ответы [ 3 ]

0 голосов
/ 22 мая 2019

Итак, если вы хорошо понимаете, вы хотите и совет от продукта A вернуть название продукта B. Вы можете сделать это, создав несколько методов, связанных с одной и той же моделью.

Ваши модели будут выглядеть аналогичноthis:

class Product extends Model
{
    public function advices()
    {
        return $this->hasMany('App\ProductAdvice', 'product_id');
    }

    public function relations()
    {
        return $this->hasMany('App\ProductAdvice', 'related_id');
    }
}

class ProductAdvice extends Model
{
    public function product()
    {
        return $this->belonsTo('App\Product', 'product_id');
    }

    public function relation()
    {
        return $this->belonsTo('App\Product', 'related_id');
    }
}

Затем вам нужно будет создать еще один столбец в вашем имени talbe: related_id (это может быть что-то другое, просто сделайте так, чтобы оно совпадало в вашей модели. Вы также можете изменить отношения () и отношение () метод с любым именем, которое вы хотите.)

После этого, как вы храните свои данные.Вы должны заставить свой код связывать хорошую модель продукта с вашим product_id и related_id.Сюда.Вы можете иметь $advice->product->name === 'iPhone' && $advice->relation->name === 'Samsung S10'

0 голосов
/ 22 мая 2019

На данный момент найдено подобное решение.

// Модель ProductAdvice

protected $table = 'product_advices';

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

public function product() {
    return $this->belongsTo('App\Product', 'product_id');
}

public function advicedProduct()
{
    return Product::where('id', $this->product_advice_id)->first();
}

// Модель продукта

public function advices()
{
    return $this->hasMany('App\ProductAdvice', 'product_id');
}

Как я показываю это на виде

@foreach($product->advices as $advice)
 <li>{{ $advice->body }} - {{ $advice->advicedProduct()->name }}</li>
@endforeach
0 голосов
/ 22 мая 2019

РЕДАКТИРОВАТЬ 2

После вашего ответа я понял, что вы хотите.

Просто обновите модель ProductAdvice, чтобы иметь другие отношения, например:

class ProductAdvice extends Model
{
    public function product()
    {
        return $this->belonsTo('App\Product', 'product_id');
    }

    public function related()
    {
        return $this->belonsTo('App\Product', 'product_advice_id');
    }
}

Тогда выможет сделать:

$product = Apple
$product->advices->message = 'blablabla'
$product->advices->related = 'ProductX'

Если вам нужно обратный порядок, $advice->product->related добавьте те же отношения в вашей модели продукта.

РЕДАКТИРОВАТЬ 1

Извините, выредактировал сообщение после моего ответа ...

Не могли бы вы объяснить необходимость 'product_advice_id'?У вас уже есть product_id.

Если вам не нужна сводная таблица, например: Product -> ProductAdvice -> Advice, которая не нужна в вашем случае, так как вы можете просто поместить информацию совета в таблицу Advice исвяжите его с продуктом (принадлежит), устраняя необходимость в сводке ProductAdvice.

Я думаю, что ваша структура должна быть такой:

Модель продукта со всем продуктомданные

ProductAdvice модель с product_id и информация о совете (сообщение, рейтинг и т. д.)

Затем ваш продукт имеет много советов, и ваш совет принадлежит вам.Продукт:

class Product extends Model
{
    public function advices()
    {
        return $this->hasMany('App\ProductAdvice', 'product_id');
    }
}

class ProductAdvice extends Model
{
    public function product()
    {
        return $this->belonsTo('App\Product', 'product_id');
    }
}

Наконец, вы можете запросить советы по конкретному продукту, чтобы получить информацию о совете:

$product->advices->message
$product->advices->rating

или запросить название продукта, если у вас есть совет:

$advice->product->name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...