Laravel 5.6.17 Модель имеет один над несколькими таблицами - PullRequest
0 голосов
/ 17 октября 2018

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

db-структура

И это мой исходный код:

  • AddressBookController.php
        namespace App\Http\Controllers;

        use App\AddressBook as AB;
        use Illuminate\Http\Request;
        use Illuminate\Support\Facades\Validator;

        class AddressBookController extends Controller
        {
            /**
             * Display a listing of the resource.
             *
             * @return \Illuminate\Http\Response
             */
            public function index()
            {
                $entries = AB::all();

                return view('addressBook')->with([
                    'class' => __CLASS__,
                    'function' => __FUNCTION__,
                    'line' => __LINE__,
                    'entries' => $entries,
                ]);
            }
        }
  • Модель AddressBook.php

        namespace App;
    
        use Illuminate\Database\Eloquent\Model;
    
    
        class AddressBook extends Model
        {
            protected $table = 'address';
            protected $primaryKey = 'address_id';
            protected $keyType = 'int';
            public $incrementing = true;
            public $timestamps = false;
            protected $searchable = [
                'columns' => [
                    'address.address_surname' => 10,
                    'address.address_company' => 5,
                    'address.address_vatid' => 2,
                ],
            ];
    
            public function country() {
                return $this->hasOne('country', 'country_id', 'country_id');
            }
    
            public function addresstype() {
                return $this->hasOne('addresstype', 'addresstype_id', 'addresstype_id');
            }
        }
    
  • Модель Country.php

        namespace App;
    
        use Illuminate\Database\Eloquent\Model;
    
        class Country extends Model
        {
            protected $table = 'country';
            protected $primaryKey = 'country_id';
            protected $keyType = 'int';
            public $incrementing = true;
            public $timestamps = false;
    
            public function translation() {
                return $this->hasOne('translations', 'translations_id', 'translations_id');
            }
    
            public function addressbook() {
                return $this->belongsTo('address', 'country_id', 'country_id');
            }
        }
    
  • Модель AddressType

        namespace App;
    
        use Illuminate\Database\Eloquent\Model;
    
        class AddressType extends Model
        {
            protected $table = 'addresstype';
            protected $primaryKey = 'addresstype_id';
            protected $keyType = 'int';
            public $incrementing = true;
            public $timestamps = false;
    
            public function translation() {
                return $this->hasOne('translations', 'translations_id', 'translations_id');
            }
    
            public function addressbook() {
                return $this->belongsTo('address', 'addresstype_id', 'addresstype_id');
            }
        }
    
  • Модель Translation.php

        namespace App;
    
        use Illuminate\Database\Eloquent\Model;
    
        class Translation extends Model
        {
            protected $table = 'translations';
            protected $primaryKey = 'translations_id';
            protected $keyType = 'int';
            public $incrementing = true;
            public $timestamps = false;
    
            public function country() {
                return $this->belongsTo('country', 'translations_id', 'translations_id');
            }
    
            public function addresstype() {
                return $this->belongsTo('addresstype', 'translations_id', 'translations_id');
            }
        }
    

Запрос "$ records = AB :: all (); "работает в целом, но я получаю идентификаторы и, возможно, я совершенно не прав, но я думал, что данные из внешних ключей будут заменены соответствующими моделями (если они настроены правильно).поэтому мой вопрос:

a.я сделал ошибку во время конфигурации и если да, где именно ошибка?
или
b.мое предположение о замене идентификаторов объектами совершенно неверно?

Заранее спасибо!Стив

1 Ответ

0 голосов
/ 17 октября 2018

Модели Laravel Eloquent не заменяют внешние ключи активных записей на реляционные данные, они только добавляют новое свойство с тем же именем, что и метод, относящийся к классам, и в это свойство он помещает все экземпляры Model полученного результата.запрос, это ТОЛЬКО если вы обращаетесь к свойству, которое называется Eager Loading.

Это объясняется здесь (Официальная документация)

$addressBook = App\AddressBook::find(1); //this only will return the active record with the id 1  and nothig more.

$addressBook->country; // The property "country" does not exist in the AddressBook Classs but eloquent models will return a "fake" property with the value of the result of the query by the method with the same name (only if the method returns an Eloquent Relation).

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

Если вы хотите загрузить отношение в наборе моделей одновременномодели извлекаются из БД, которые вам нужны для явного определения отношений, которые вы хотите загрузить.

$addressBook = App\AddressBook::with(['country', 'addresstype', 'anotherRelation'])->get(); // this will retrive all the addressBook models and in each one will attach the relations specified.

[РЕДАКТИРОВАНИЕ] Кроме того, вы должны поместить все пространство имен связанного класса модели в методы отношений, так что вам нужнозаменить как:

    class Translation extends Model
    {
        protected $table = 'translations';
        protected $primaryKey = 'translations_id';
        protected $keyType = 'int';
        public $incrementing = true;
        public $timestamps = false;

        // ****** You need to put the entire namespace of the Model class
        public function country() {
            return $this->belongsTo('App\Country', 'translations_id', 'translations_id');
    }
...