Laravel 5.6.17模型具有多个表的One

时间:2018-10-17 13:49:43

标签: laravel model belongs-to has-one

我对Laravel还是很陌生,现在我正尝试将以前的应用程序的一部分从一个小型的自编写框架移至Laravel。通讯录是多语言的,因此表结构稍微复杂一些。

db-structure

这是我的源代码:

  • AddressBookController.php
Processing by ContentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"rM9i4hOlaYpVCmaUpHVRmh9N/QqI+nbnPvIJp3k9VlJ1U8rSb7FNTv9kqlR0P0LayZ6nUto2ekYXoTrCy45mWw==", "content"=>{"post_copy"=>"Testing for Stack Over Flow", "price"=>"10", "images"=>[], "is_instagram"=>"1"}, "commit"=>"Submit for Approval", "campaign_id"=>"1"}
  Campaign Load (0.2ms)  SELECT  "campaigns".* FROM "campaigns" WHERE "campaigns"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/contents_controller.rb:126
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 2], ["LIMIT", 1]]
  ↳ app/controllers/contents_controller.rb:25
  CACHE Campaign Load (0.0ms)  SELECT  "campaigns".* FROM "campaigns" WHERE "campaigns"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/contents_controller.rb:29
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/contents_controller.rb:32
Unpermitted parameter: :images
   (0.1ms)  begin transaction
  ↳ app/controllers/contents_controller.rb:39
  Content Create (1.1ms)  INSERT INTO "contents" ("user_id", "campaign_id", "post_copy", "is_instagram", "price", "transaction_fee", "total", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)  [["user_id", 2], ["campaign_id", 1], ["post_copy", "Testing for Stack Over Flow"], ["is_instagram", 1], ["price", 10], ["transaction_fee", 1], ["total", 11], ["created_at", "2018-10-17 14:03:08.805281"], ["updated_at", "2018-10-17 14:03:08.805281"]]
  ↳ app/controllers/contents_controller.rb:39
   (6.1ms)  commit transaction
  ↳ app/controllers/contents_controller.rb:39
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  ↳ app/models/content.rb:16
   (0.2ms)  begin transaction
  ↳ app/models/content.rb:18
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ app/models/content.rb:18
  Notification Create (0.7ms)  INSERT INTO "notifications" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["content", "New Request from Influencer"], ["user_id", 1], ["created_at", "2018-10-17 14:03:08.841715"], ["updated_at", "2018-10-17 14:03:08.841715"]]
  ↳ app/models/content.rb:18
   (3.8ms)  commit transaction
  ↳ app/models/content.rb:18
[ActiveJob] Enqueued NotificationJob (Job ID: 61665383-2b84-4215-95c2-47f6a5b98153) to Async(default) with arguments: #<GlobalID:0x00007fdf094d0928 @uri=#<URI::GID gid://Notification/17>>
Redirected to http://localhost:3000/campaigns/1
  Notification Load (0.4ms)  SELECT  "notifications".* FROM "notifications" WHERE "notifications"."id" = ? LIMIT ?  [["id", 17], ["LIMIT", 1]]
Completed 302 Found in 71ms (ActiveRecord: 14.2ms)
  • 模型AddressBook.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,
                    ]);
                }
            }
    
  • 模型Country.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');
            }
        }
    
  • 模型AddressType

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

        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');
            }
        }
    

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

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

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

提前谢谢! 史蒂夫

1 个答案:

答案 0 :(得分:0)

Laravel雄辩的模型不会用关系数据替换活动记录的外键,它只会附加一个新属性,该属性的名称与关联类的方法相同,并且在该属性中它将结果的所有Model实例放入查询,仅当您访问该属性时,才称为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).

这种雄辩的行为是很自然的,并且是最小化查询数量的一种非常聪明的方法,雄辩不会在不需要时加载任何关系。

如果要在从数据库检索模型的同时将一组关系加载到模型中,则需要明确指定要加载的关系。

$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');
    }