Есть ли способ динамически вызывать отношения laravel в этом сценарии? - PullRequest
0 голосов
/ 19 марта 2020

Я работаю над проектом Laravel с несколькими моделями. Моя основная модель Product имеет несколько взаимосвязей со многими вторичными моделями в приложении. Я создал необходимые методы для настройки отношений на соответствующих моделях, дело в том, что теперь мне нужен чистый способ добавить или удалить связанные вторичные модели. Определив мой продукт как:

class Product extends Model 
{

    public function equipments()
    {
        return $this->belongsToMany('App\Equipment', 'product_has_equipment');
    }

    public function rawmaterials()
    {
        return $this->belongsToMany('App\RawMaterial', 'product_has_raw_material')->withPivot('composition');
    }

    public function indirectcosts()
    {
        return $this->belongsToMany('App\IndirectCost', 'product_has_indirect_cost');
    }

    public function presentations()
    {
        return $this->belongsToMany('App\Presentation', 'product_has_presentation');
    }
}

Я попытался сделать следующее:

public function addRelated(string $type, array $items)
{
    $this->__call($type, [])->attach($items);
}

Я думаю, что таким образом можно было бы просто указать строку, соответствующую одному из имен отношений и с помощью __call он может вызываться динамически, поэтому, если я передам 'equipments' в виде $ type для вышеуказанной функции, я надеялся, что внутренний вызов будет:

$this->equipments()->attach($items);

Но вместо этого Я получил ошибку

Ridiculous error

Это кажется странным, учитывая, что "неопределенный метод" точно такой же, как тот, который рекомендован laravel в том же page.

Примите во внимание, что я действительно знаю, что этот подход может быть небезопасным с точки зрения кода, но этот проект будет API, работающим на локальном сервере, который будет использоваться только электронным приложением, поэтому безопасность не мой приоритет в этом деле.

1 Ответ

1 голос
/ 19 марта 2020

проверьте исходный код Laravel модель

/**
     * Handle dynamic method calls into the model.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        if (in_array($method, ['increment', 'decrement'])) {
            return $this->$method(...$parameters);
        }

        return $this->forwardCallTo($this->newQuery(), $method, $parameters);
    }

и forwardCall говорит

/**
     * Forward a method call to the given object.
     *
     * @param  mixed  $object
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    protected function forwardCallTo($object, $method, $parameters)
    {
        try {
            return $object->{$method}(...$parameters);
        } catch (Error | BadMethodCallException $e) {
            $pattern = '~^Call to undefined method (?P<class>[^:]+)::(?P<method>[^\(]+)\(\)$~';

            if (! preg_match($pattern, $e->getMessage(), $matches)) {
                throw $e;
            }

            if ($matches['class'] != get_class($object) ||
                $matches['method'] != $method) {
                throw $e;
            }

            static::throwBadMethodCallException($method);
        }
    }

, поскольку $this->newQuery() возвращает Illuminate\Database\Eloquent\Builder;, что не хотел методы

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