Laravel Eloquent с методом () работает с «где», но не работает с «Model :: find ()» - PullRequest
0 голосов
/ 20 мая 2018

Я хочу иметь отношения между 3 таблицами, используя Laravel Eloquent with() метод .это мой код ( отношения установлены в моделях ):

    $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 ▶}
  ]
}

когда я заменяю ->get() на ->first(), он возвращает только 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();
    });

1 Ответ

0 голосов
/ 20 мая 2018

Сначала я отошлю вас к этому ответу , но ради записи я еще раз объясню, как я понимаю:

Когда вы используете метод find(), экземпляр моделиуже возвращено (это не построитель запросов), поэтому использование with() для результата find сделает новый запрос к базе данных, затем вызовет get() для всех записей, тогда как вызов first() вернет первыйзапись (по id).

Я предложил способы сделать это в случае, если вы все еще хотите придерживаться find()

  • Позвольтеfind() после запроса (загружен).Пример:

    $request_form = RequestForm::with(['RequestFormsCheck' => function ($q) {
        $q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions');
    }])->find(7);
    
  • Использовать load() после поиска (Lazy загружен) - у вас есть результат, затем загрузите соответствующие модели.Пример:

    $request_form = RequestForm::find(7)->load(['RequestFormsCheck' => function ($q) {
        $q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions');
    }]);
    
  • Придерживайтесь вызова with() (тот, который работал) на весь запрос, прежде чем вызывать окончательный результат.Я думаю, что это лучший способ сделать это, так как вам нужно только один RequestForm, затем много отношений с этим

Мое общее понимание того, как работает with(), относится к построителю запросов, поэтому вы все равно должны собирать запрос до того, как with() будет актуален (возможно, эта мысль должна быть обновлена).

Вы можетенужно читать больше на Eager Загрузка - в документах Laravel

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...