【问题标题】:Laravel 5.6.17 Model hasOne over multiple tablesLaravel 5.6.17 模型 hasOne over 多个表
【发布时间】:2018-10-17 13:49:43
【问题描述】:

我对 Laravel 很陌生,现在我正在尝试将以前的应用程序的一部分从一个小型的自写框架移动到 Laravel。通讯录是多语言的,所以表结构有点复杂。

db-structure

这是我的源代码:

  • 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');
            }
        }
    
  • 模型国家.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');
            }
        }
    
  • 型号地址类型

        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');
            }
        }
    
  • 模型翻译.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');
            }
        }
    

请求“$entries = AB::all();”一般工作,但我得到了 id,也许我在这里完全错了,但我认为来自外键的数据将被相应的模型替换(如果配置正确)。所以我的问题是:

一个。我在配置过程中是否犯了错误,如果是,错误究竟出在哪里?

湾。我用对象替换 id 的假设是完全错误的吗?

提前致谢! 史蒂夫

【问题讨论】:

    标签: laravel model belongs-to has-one


    【解决方案1】:

    Laravel Eloquent 模型不会用关系数据替换活动记录的外键,它只会附加一个与关联类的方法同名的新属性,并在该属性中放置结果的所有模型实例查询,仅当您访问该属性时才这样做,它称为 Eager Loading。

    It is explained here (Ofiicial Documentation)

    $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 的这种行为是自然的,并且是一种非常聪明的方式来最小化查询的数量,如果不需要,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');
        }
    

    【讨论】:

    • 感谢您的澄清,但现在我有另一个问题:我在 vendor\laravel\framework\src\Illuminate 中收到错误 Class 'country' not found \Database\Eloquent\Concerns\HasRelationships.php 据我所知,模型似乎设置正确;-)
    • @gmaltasteffl 确保在您的关系定义中包含命名空间。 $this->hasOne('App\Country')
    • 不,您的模型上的设置也是错误的,您需要将每个模型的整个命名空间放在关系方法中(检查响应更新)
    猜你喜欢
    • 2013-10-19
    • 2023-02-16
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多