Laravel 4 автоматически создает отношения в базовой модели — используя «with»-массив или области видимости или что?

#php #laravel #model #eager-loading

#php #laravel #Модель #нетерпеливая загрузка

Вопрос:

Я успешно создал несколько отношений в модели. Это пользовательская модель

 <?php 
  class User extends BaseModel{ 
    protected $table = 'users';

    public function group(){
        return $this -> belongsTo('UserGroup');
    }

    ...
  } 
?>
  

и это модель группы пользователей (UserGroup.php )

 <?php class UserGroup extends BaseModel{ ... } ?>
  

Каждый пользователь может быть в одной группе (столбец базы данных называется ‘group_id’ в таблице users). Если я хочу выполнить быструю загрузку этого отношения, это отлично работает, также для других моделей.

Проблема в том, что у меня есть несколько моделей, в которых много внешних ключей, и я не хочу создавать все отношения вручную. Я хочу функцию в базовой модели, которая автоматически создает все эти отношения, например

 public function group(){
    return $this->belongsTo('Group');
}
  

на основе массива, который я бы предоставил в каждой модели, выглядит следующим образом

 protected $foreignKeys = array(array('key' => 'group', 'model' => 'UserGroup'), ...);
  

Я читал, что существует массив с именем «with», который вы можете использовать, но у меня это не сработало. Где-то еще я читал, что я должен работать с областями запросов, но я понятия не имею, как это могло бы мне помочь.

Спасибо за чтение и вашу поддержку!

С наилучшими пожеланиями, Марсель

Комментарии:

1. Ardent предоставляет что-то вроде того, что вы хотели github.com/laravelbook/ardent/blob/master/src/LaravelBook /… , но я бы не обязательно предлагал такой подход. Может быть, просто создайте больше (абстрактных?) моделей, которые вы бы расширили? И чтобы ответить на ваши опасения — ни scopes, ни with не делают того, что вам нужно.

2. Спасибо за вашу помощь. Я уже пытался работать с методом magic __call(), но затем получил сообщение об ошибке, в котором говорится, что first() не определен в классе Eloquent или около того. Я попробую еще раз с версией Ardents и сообщу вам, сработало ли это, завтра. Как бы вы это сделали с (абстрактным?) Модели?

3. Привет, @deczo, я прочитал класс Ardents, и он выглядит очень похоже на то, что я хочу иметь. Все эти процедуры проверки тоже хороши. Почему бы вам НЕ предложить такой подход? И как бы вы сделали это с моделями, которые были бы расширены? Спасибо!

4. Во-первых, я не использую Ardent, потому что нахожу его не очень гибким, когда вам нужно больше, чем просто базовые функции Eloqeunt. Чтобы ответить на ваш вопрос, приведите несколько примеров моделей, которые вам нужны, с общими отношениями.

5. Например, у меня могла бы быть FlightData -модель со следующими полями: id, origin_airport, destination_airport, date, ... и множеством других полей, которые на самом деле являются внешними ключами, точно так же, как origin_airport и destination_airport являются внешними ключами для Airport -модели. Я не хочу создавать 15 функций, которые объявляют отношения между моделями, а просто имеют для этого on array.

Ответ №1:

Ardent предоставляет нечто подобное, что вы хотели бы реализовать:https://github.com/laravelbook/ardent/blob/master/src/LaravelBook/Ardent/Ardent.php#L347-L350 .

Согласно комментариям:

Возможно, в конце концов, вы найдете решение, подобное Ardent, которое лучше подходит для вашей ситуации. Наличие всех отношений в массиве дает больше преимуществ для определения их как методов — вы можете выполнять поиск по этим массивам, если вам нужно и т.д. Так что, вероятно, это правильный путь для вас