Intereting Posts
Кодировать массив в строку JSON без индексов массива Преобразование открытого ключа RSA, от XML до PEM (PHP) PHP Proxy – базовое объяснение Простая замена шаблона var, но с завихрением В чем основное отличие между следующими утверждениями? Контактная форма подтверждения без обновления PHP EOF показывает только один результат из цикла получить текущую дату и дату после двух месяцев в php данные, введенные в текстовую область, не войдут в базу данных, разработанную с использованием php и mysqli Cucumber для PHP-приложения Должен ли я использовать фигурные скобки или конкатенатные переменные в строках? Разделить массив, но сумма каждого массива не должна превышать максимальное значение else. Нажмите на следующий индекс массива Почему SQLSTATE : общая ошибка? Передача массива в SOAP-функцию в PHP Ошибка nginx подключиться к php5-fpm.sock не удалось (13: отказ от прав)

Как установить отношения «Жестокое» принадлежит ЧЕРЕЗ другую модель в Laravel?

У меня есть модельный список, который наследуется через его отношение toTo ('Model'), по сути, принадлежит производителю, к которому принадлежит соответствующая модель.

Вот из моей модели листинга:

public function model() { return $this->belongsTo('Model', 'model_id'); } public function manufacturer() { return $this->belongsTo('Manufacturer', 'models.manufacturer_id'); /* $manufacturer_id = $this->model->manufacturer_id; return Manufacturer::find($manufacturer_id)->name;*/ } 

и моя модель производителя:

 public function listings() { return $this->hasManyThrough('Listing', 'Model', 'manufacturer_id', 'model_id'); } public function models() { return $this->hasMany('Model', 'manufacturer_id'); } 

Я могу отозвать имя $ listing-> model-> в представлении, но не $ listing-> manufacturer-> name. Это порождает ошибку. Я попробовал прокомментировать 2 строки в листинговой модели, чтобы получить эффект, поэтому я мог бы повторить $ listing-> manufacturer (), и это сработает, но это неправильно устанавливает их отношения. Как мне это сделать? Благодарю.

Пересмотренная модель листинга (спасибо ответчику):

  public function model() { return $this->belongsTo('Model', 'model_id'); } public function manufacturer() { return $this->belongsTo('Model', 'model_id') ->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id'); } 

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

Вы не должны иметь доступ к производителю напрямую из списка, так как производитель относится только к модели. Хотя вы можете с нетерпением загружать отношения производителя с объектом листинга, см. Ниже.

 class Listing extends Eloquent { public function model() { return $this->belongsTo('Model', 'model_id'); } } class Model extends Eloquent { public function manufacturer() { return $this->belongsTo('manufacturer'); } } class Manufacturer extends Eloquent { } $listings = Listing::with('model.manufacturer')->all(); foreach($listings as $listing) { echo $listing->model->name . ' by ' . $listing->model->manufacturer->name; } 

Потребовалось немного финализации, чтобы заставить ваше запрошенное решение работать. Решение выглядит так:

 public function manufacturer() { $instance = new Manufacturer(); $instance->setTable('models'); $query = $instance->newQuery(); return (new BelongsTo($query, $this, 'model_id', $instance->getKeyName(), 'manufacturer')) ->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id') ->select(DB::raw('manufacturers.*')); } 

Я начал с работы с запросом и создания ответа от этого. Запрос, который я искал для создания, был следующим:

 SELECT * FROM manufacturers ma JOIN models m on m.manufacturer_id = ma.id WHERE m.id in (?) 

Запрос, который обычно создается, return $this->belongsTo('Manufacturer');

 select * from `manufacturers` where `manufacturers`.`id` in (?) 

? будет заменено значением столбцов manufacturer_id из таблицы списков. Этот столбец не существует, поэтому будет вставлен один 0, и вы никогда не вернете производителя.

В запросе, который я хотел воссоздать, я сдерживал models.id . Я мог бы легко получить доступ к этому значению в моих отношениях, указав внешний ключ. Таким образом, отношения стали

 return $this->belongsTo('Manufacturer', 'model_id'); 

Это вызывает тот же запрос, что и раньше, но заполняет ? с model_ids. Таким образом, это возвращает результаты, но в целом неверные результаты. Затем я попытался изменить базовую таблицу, которую я выбирал. Это значение выводится из модели, поэтому я изменил переданную модель на Model .

 return $this->belongsTo('Model', 'model_id'); 

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

 return $this->belongsTo('Model', 'model_id') ->join('manufacturers', 'manufacturers.id', '=', 'models.manufacturer_id'); 

Это приблизило нас на один шаг, создав следующий запрос:

 select * from `models` inner join `manufacturers` on `manufacturers`.`id` = `models`.`manufacturer_id` where `models`.`id` in (?) 

Отсюда я хотел бы ограничить столбцы, которые я запрашивал только для столбцов производителя, для этого я добавил спецификацию выбора. Это привело к:

return $ this-> attribTo ('Model', 'model_id') -> join («производители», «производители.», «=», «models.manufacturer_id») -> select (DB :: raw («производители . * '));

И получил запрос к

 select manufacturers.* from `models` inner join `manufacturers` on `manufacturers`.`id` = `models`.`manufacturer_id` where `models`.`id` in (?) 

Теперь у нас есть 100% действительный запрос, но объекты, возвращаемые из отношения, имеют тип Model not Manufacturer . И вот тут вошла последняя битка. Мне нужно было вернуть Manufacturer, but wanted it to constrain by the table in the where clause. I created a new instance of Manufacturer and set the table to моделей table in the where clause. I created a new instance of Manufacturer and set the table to table in the where clause. I created a new instance of Manufacturer and set the table to модели и вручную создал отношения.

Важно отметить, что экономия не будет работать .

 $listing = Listing::find(1); $listing->manufacturer()->associate(Manufacturer::create([])); $listing->save(); 

Это создаст новый производитель, а затем обновит listings.model_id до идентификатора нового производителя.