Хорошо, так что ошибка говорит
Вызов неопределенного метода Illuminate \ Database \ Eloquent \ Builder :: team ()
Это означает, что метод team()
не определен в классе Builder
Теперь класс Builder находится в vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php
в пространстве имен Illuminate\Database\Eloquent
Логически следует, что для функции с именем team()
невозможнобыть там правильно?
Что такое команда ()? тогда и как я могу это назвать?
team()
- это функция внутри вашей модели app/User.php
, и она возвращает hasOne
функцию
Хорошо, так где же hasOne()
?
hasOne
находится в признаке vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php
под пространством имен Illuminate\Database\Eloquent\Concerns
Смотрите здесь
namespace Illuminate\Database\Eloquent\Concerns;
// Imports ommitted for brevity
trait HasRelationships
{
// Other methods ommitted for brevity
/**
* Define a one-to-one relationship.
*
* @param string $related
* @param string $foreignKey
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function hasOne($related, $foreignKey = null, $localKey = null)
{
$instance = $this->newRelatedInstance($related);
$foreignKey = $foreignKey ?: $this->getForeignKey();
$localKey = $localKey ?: $this->getKeyName();
return $this->newHasOne($instance->newQuery(), $this, $instance->getTable() . '.' . $foreignKey, $localKey);
}
// Other methods are omitted for brevity
Но как это называется? Я не использую черту HasRelationships
Это правда, класс app/User.php
не использует черту HasRelationships
, но расширяет класс, который *
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
* не напрямую, хотя
Подсветка \ Foundation \ Auth \ Расширения пользователя Подсветка \ База данных \ Eloquent \ Модель
См. Здесь
namespace Illuminate\Foundation\Auth;
// Other Imports ommitted for brevity
use Illuminate\Database\Eloquent\Model;
class User extends Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}
И
Подсветка \ База данных \ Eloquent \ Model использует черту Concerns \ HasRelationships
См. Здесь
namespace Illuminate\Database\Eloquent;
// Imports ommitted for brevity
abstract class Model implements Arrayable, ArrayAccess, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
{
use Concerns\HasAttributes,
Concerns\HasEvents,
Concerns\HasGlobalScopes,
Concerns\HasRelationships, // <-- THERE IT IS HERE!!!!
Concerns\HasTimestamps,
Concerns\HidesAttributes,
Concerns\GuardsAttributes,
ForwardsCalls;
// Rest of class ommitted for brevity
Подождите! как этот класс узнает, откуда взята черта Concerns\HasRelationships
без импорта?
Поскольку Concerns - это пространство имен, добавленное (или вложенное в) к тому же пространству имен, этот класс определен в
Этот класс находится в Illuminate\Database\Eloquent
и HasRelationships
в Illuminate\Database\Eloquent\Concerns
, поэтому достаточно простого вызова Concerns\HasRelationships
Теперь черта HasRelationships
имеет функцию hasOne
Хорошо, как избежать этой ошибки?
Убедитесь, что вы вызываете отношение, определенное в модели, из экземпляра модели, а не из построителя запросов
Пример
Неверно
User::where('name', 'John Doe')->teams;
Правильно
User::where('name', 'John Does')->first()->teams;
Но почему?
Хорошо, любая операция SQL, которую вы выполняете на модели до , вы получитемодель является экземпляром Query Builder
Но как только вы получите саму модель, например, с first()
, вы можете вызвать отношение
Обновление: чтобы ответить на конкретный сценарий вопроса
Вы можете выбрать более одной модели, поэтому не идеальнофункция связи team()
для каждой записи после ее выборки
Решение?
Стремительная загрузка
Использование with
метод для включения данных отношений в коллекцию, извлеченную с помощью get()
Пример
Допустим, у меня есть User
и Profile
У каждого пользователя есть одини только один профиль, поэтому я определяю отношение hasOne
для User
модели
public function profile()
{
return $this->hasOne(Profile::class);
}
Теперь нам нужен внешний ключ в миграции, чтобы связать таблицу profiles
с таблицей users
Schema::create('profiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('age'); // Column to test with
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
Теперь давайте посеем некоторые данные
public function run()
{
factory(User::class, 10)->create()->each(function ($user) {
$user->profile()->create(['age' => rand(20, 60)]);
});
}
Теперь давайте откроем ремесленника и посмотрим, что произойдет
>>> App\User::take(10);
=> Illuminate\Database\Eloquent\Builder {#3067}
take()
Функция на модели User возвращаетЭкземпляр Builder
Давайте попробуем получить профиль для этого
>>> App\User::take(10)->profile();
Ошибка
BadMethodCallException с сообщением «Вызов неопределенного метода Illuminate / Database / Eloquent / Builder:: profile () '
Но теперь мы знаем, почему
Теперь давайте попробуем Eager Загрузка
>>> App\User::take(10)->with('profile');
=> Illuminate\Database\Eloquent\Builder {#3056}
Возвращает построитель запросов
Давайте назовем get()
для этого
>>> App\User::take(10)->with('profile')->get();
Теперь мы получаем нашу коллекцию данных
=> Illuminate\Database\Eloquent\Collection {#3070
all: [
App\User {#3022
id: 1,
name: "Augusta Botsford MD",
email: "xwaelchi@example.net",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3095
id: 1,
age: 29,
user_id: 1,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3017
id: 2,
name: "Olga Leannon",
email: "ufay@example.com",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3096
id: 2,
age: 24,
user_id: 2,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3019
id: 3,
name: "Bria Prosacco DDS",
email: "hartmann.trystan@example.com",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3097
id: 3,
age: 43,
user_id: 3,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3054
id: 4,
name: "Clare Bayer",
email: "rosalinda60@example.org",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3098
id: 4,
age: 52,
user_id: 4,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3058
id: 5,
name: "Vickie Kub",
email: "katherine.abbott@example.com",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3099
id: 5,
age: 42,
user_id: 5,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3059
id: 6,
name: "Tressie Gottlieb",
email: "elmira.osinski@example.net",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3100
id: 6,
age: 21,
user_id: 6,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3042
id: 7,
name: "Saige Pollich",
email: "gkemmer@example.org",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3101
id: 7,
age: 24,
user_id: 7,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3087
id: 8,
name: "Dr. Emiliano Sauer",
email: "marks.florida@example.net",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3102
id: 8,
age: 42,
user_id: 8,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3086
id: 9,
name: "Genoveva Abshire",
email: "colt.harber@example.com",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3103
id: 9,
age: 27,
user_id: 9,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
App\User {#3088
id: 10,
name: "Dimitri Moore",
email: "slockman@example.net",
email_verified_at: "2019-09-30 16:40:12",
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
profile: App\Profile {#3104
id: 10,
age: 30,
user_id: 10,
created_at: "2019-09-30 16:40:12",
updated_at: "2019-09-30 16:40:12",
},
},
],
}
Надеюсь, это прояснит ситуацию