Указание столбца идентификатора цели метода morphTo

Есть ли способ указать столбец целевого идентификатора в методе morphTo?

Я приведу пример, который есть в документации для laravel:

Пост - идентификатор, текст

Видео — идентификатор, URL

Комментарий — идентификатор, текст, commentable_id, commentable_type

Но что, если идентификаторы поста и видео были переименованы в custom_id? Как бы я тогда настроил свою красноречивую модель? Спасибо.

Изменить:

Я до сих пор не понимаю, вот полный код:

Структура таблицы:

comments - id, text, commentable_id, commentable_type, user_id
posts - custom_id, text
videos - custom_id, url
users - id, name, email, password,...

Модель комментария:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    public function commentable()
    {
        return $this->morphTo();
    }
}

Видео модель:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{

    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable', 'commentable_type', 'commentable_id', 'custom_id');
    }
}

Почтовая модель:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable', 'commentable_type', 'commentable_id', 'custom_id');
    }
}

Пользовательская модель:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function comments()
    {
        return $this->hasMany('App\Comment');
    }
}

ТестКонтроллер:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;

class TestController extends Controller
{
    public function test()
    {
        $user = User::first();
        $comments = $user -> comments;

        foreach ($comments as $comment)
        {
            return $comment -> commentable;
        }
    }
}

И он по-прежнему выдает исключение запроса Неизвестный столбец posts.id

Пожалуйста, объясни. Спасибо.


person maranovot    schedule 21.05.2017    source источник


Ответы (1)


Вы можете установить собственное имя поля идентификатора в отношении.

public function comments()
{
    return $this->morphMany('App\Comment', 'commentable', 'commentable_type', 'commentable_id', 'custom_id');
}

Есть параметры

public function morphMany($related, $name, $type = null, $id = null, $localKey = null);

Редактировать: пройдя через все это, я обнаружил, что использование пользовательского идентификатора работает только с родительским извлекает дочерние отношения. Но терпит неудачу при попытке заставить родителя использовать детей. Таким образом, получение сообщения или видео из комментария не удастся.

Есть активное предложение о внутренних компонентах laravel, чтобы добавить функцию, позволяющую указать пользовательский идентификатор, чтобы это работало. https://github.com/laravel/internals/issues/587

person Sandeesh    schedule 21.05.2017
comment
Итак, я попробовал то, что вы предложили, но, когда я, например, устанавливаю отношения «многие ко многим» между пользователем и комментарием (не имеет особого смысла, но, например). Настраиваю отношения, но когда я делаю что-то вроде: foreach (User::first() -> comments as $comment) { return $comment -> commentable }... Все, что я получаю, это Неизвестный столбец posts.id.. . - person maranovot; 22.05.2017
comment
@M.Novotny Пример относился к отношениям один ко многим. Вам нужно настроить отношения «многие ко многим» по-разному. Проверьте это здесь laravel.com/docs/5.4/ также вы можете получить собственный идентификатор. morphToMany($related, $name, $table = null, $foreignKey = null, $relatedKey = null, $inverse = false) - person Sandeesh; 22.05.2017
comment
Но когда я меняю custom_id обратно на id, он работает без проблем. Итак, единственная причина, по которой красноречивый не знает, какой идентификатор искать, заключается в том, что я не установил отношение многие ко многим? Честно говоря, я стараюсь держаться подальше от полиморфных отношений «многие ко многим», я предпочитаю создавать супертаблицы и обрабатывать полиморфизм на уровне базы данных. Тогда вся структура имеет для меня гораздо больший смысл, чем что-то способное здесь и что-то способное там. Но странно, что красноречивый прекрасно понимает отношения с id, но как только вы меняете имя столбца на custom_id, оно ломается. - person maranovot; 22.05.2017
comment
«Что-то способное» — это просто соглашение об именах. В конце концов, когда вы смотрите на структуру таблицы и видите, как laravel создает запрос, это именно то, что вы бы назвали простым и понятным. Причина усложнения состоит в том, чтобы сделать его беглым с красноречивым. Но после использования его в паре проектов вам не покажется это сложным. - person Sandeesh; 22.05.2017
comment
И где я могу увидеть, как laravel создает запросы? - person maranovot; 22.05.2017
comment
@M.Novotny, вы можете добавить прослушиватель для регистрации всех запросов или использовать панель отладки github.com/barryvdh/ laravel-debugbar. Я бы рекомендовал использовать панель отладки в настройках разработчика, так как она очень помогает во многих аспектах. - person Sandeesh; 22.05.2017
comment
Давайте продолжим это обсуждение в чате. - person Sandeesh; 22.05.2017