簡體   English   中英

Laravel Eloquent with()方法與'where'一起使用但不適用於'Model :: find()'

[英]Laravel Eloquent with() method works with 'where' but doesn't work with 'Model::find()'

我希望使用Laravel Eloquent with() 方法在3個表之間建立關系。 這是我的代碼( 關系在模型中設置 ):

    $request_form = RequestForm::find(7)->with(['RequestFormsCheck' => function ($q) {
        $q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions');
    }])->get();

    dd($request_form);

但是此代碼返回所有request forms除了僅返回id = 7這是輸出:

Collection {#895 ▼
  #items: array:4 [▼
    0 => RequestForm {#796 ▶}
    1 => RequestForm {#797 ▶}
    2 => RequestForm {#798 ▶}
    3 => RequestForm {#799 ▶}
  ]
}

當我用->first()替換->get() ,它只返回request form ,但其id為1 :(

但是這段代碼效果很好:

        $request_form = RequestForm::where('id', 7)->with(['RequestFormsCheck' => function ($q) {
            $q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions');
        }])->first();

        dd($request_form->toArray());

這是它的輸出( 這是我期望得到的 ):

array:12 [▼
  "id" => 7
  "name" => "Jack"
  "email" => "jack@gmail.com"
  "telephone" => null
  "description" => "..."
  "site" => "http://branch.local/"
  "item_id" => 10
  "lang" => "en"
  "read" => 1
  "created_at" => "2018-05-15 11:09:47"
  "updated_at" => "2018-05-20 05:24:41"
  "request_forms_check" => array:1 [▼
    0 => array:8 [▼
      "id" => 1
      "request_form_id" => 7
      "type" => 2
      "request_forms_check_options_id" => null
      "description" => "custom note"
      "created_at" => "2018-05-15 11:48:36"
      "updated_at" => "2018-05-15 11:48:36"
      "request_forms_check_options" => null
    ]
  ]
]

這些是我的遷移:

    Schema::create('request_forms', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name', 100)->nullable();
        $table->string('email', 100)->nullable();
        $table->string('telephone', 20)->nullable();
        $table->text('description')->nullable();
        $table->string('site', 100);
        $table->integer('item_id');
        $table->string('lang');
        $table->timestamps();
    });

    Schema::create('request_forms_check_options', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title', 500);
        $table->timestamps();
    });

還有這個

    Schema::create('request_forms_checks', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('request_form_id')->unsigned();
        $table->foreign('request_form_id')->references('id')->on('request_forms')->onDelete('cascade');
        $table->tinyInteger('type')->comment("1: option, 2:description");
        $table->integer('request_forms_check_options_id')->unsigned()->nullable();
        $table->foreign('request_forms_check_options_id')->references('id')->on('request_forms_check_options')->onDelete('cascade');
        $table->text('description')->nullable();
        $table->timestamps();
    });

首先,我會向您推薦這個答案,但為了記錄,我會再次解釋,因為我理解:

當你使用find()方法時,已經返回了Model的一個實例(這不是查詢構建器),這就是為什么在find的結果上使用with()會對數據庫執行一個新的查詢,然后在那個上調用get()返回整個記錄,而調用first()將返回第一條記錄(按id)。

我提出了一些方法來解決這個問題,以防你仍然想堅持使用find()

  • find()在查詢之后(eager loaded)。 例:

     $request_form = RequestForm::with(['RequestFormsCheck' => function ($q) { $q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions'); }])->find(7); 
  • 查找后使用load() (延遲加載) - 您有結果然后加載相關模型。 例:

     $request_form = RequestForm::find(7)->load(['RequestFormsCheck' => function ($q) { $q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions'); }]); 
  • 在調用最終結果之前,堅持在整個查詢中調用with() (有效的)。 我認為這是最好的方法,因為你只需要一個 RequestForm,然后需要很多關系

我對with()工作的一般理解是在查詢構建器上,因此在with()相關之前with()您仍然必須將查詢聚集在一起(這種想法可能需要更新)。

您可能需要閱讀有關Eager Loading的更多信息- 在Laravel文檔中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM