#php #laravel #laravel-7
#php #laravel #laravel-7
Вопрос:
У меня есть следующие 3 таблицы
Классы
id subject
Зарегистрированные студенты
id user_id class_id
Публикации
id class_id type attachment
Модели
Classroom.php
public function posts()
{
return $this->hasMany(Post::class);
}
RegisteredStudents.php
public function classroom()
{
return $this->belongsTo(Classroom::class);
}
Post.php
public function classroom()
{
return $this->belongsTo(Classroom::class);
}
Теперь мне нужно получить все записи определенного класса, под которым зарегистрирован студент.
например, студент зарегистрирован для класса, идентификатор которого равен 1 в таблице classroom. таким образом, в таблице registered_students будет отмечено, что этот конкретный пользователь зарегистрирован в этом конкретном классе. Каждый класс может иметь несколько записей в таблице post. И пользователю необходимо получить все сообщения своего класса.
Я пытаюсь сделать что-то вроде этого:
$registered_classes = RegisteredStudent::where('user_id',$user->id)
->where(function ($q) use ($class_id){
Post::where('class_id',$class_id);
})->get();
что определенно неверно. каким будет правильный запрос для этого.
Ответ №1:
Вы создали RegisteredStudent
модель с classroom
отношением. Проблема в том, что если ваше foreign_key
поведение отличается от поведения Laravel, вы должны включить его в отношение. Вот так:
Classroom.php
public function posts(): HasMany
{
return $this->hasMany(Post::class, 'class_id');
}
* Поведение Laravel требует, чтобы вы использовали classroom_id
вместо class_id
RegisteredStudent.php
public function classroom(): BelongsTo
{
return $this->belongsTo(Classroom::class, 'class_id');
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
Post.php
public function classroom(): BelongsTo
{
return $this->belongsTo(Classroom::class, 'class_id');
}
Более подробно о поведении Laravel с полными примерами здесь
* Отредактировано
Затем, если вы хотите получить все записи определенного класса, в котором зарегистрирован учащийся, вы можете использовать with
метод:
public function getAllPostsClassroom()
{
$registeredUser = RegisteredStudent::where('user_id', $user->id)->with(['classroom.posts' => function($query) use ($class_id) {
$query->where('class_id', $class_id);
}])->first();
}
И вы получите все Posts
внутри Classroom
зарегистрированного пользователя
Комментарии:
1. это не дает ПОЛНОГО ответа на вопрос. Он в первую очередь запрашивает правильный запрос
2. каким будет запрос?
3. Отредактировано @OsmanRafi. Пожалуйста, дайте мне знать, работает ли это.
4. этот запрос не возвращает Posts, а возвращает экземпляр RegiateredStudent
5. У них должна быть установлена
hasManyThrough
связь отUser
доClassroom
.RegisteredStudent
это просто сводная модель, и она не должна напрямую участвовать в запросе.
Ответ №2:
Сначала вам нужно исправить отношения, как TheArKa
указано в его ответе (поскольку имена таблиц и классов неправильно соответствуют соглашению laravel eloquent).
Classroom.php
public function posts()
{
return $this->hasMany(Post::class, 'class_id');
}
RegisteredStudent.php
public function classroom()
{
return $this->belongsTo(Classroom::class, 'class_id');
}
Тогда правильный запрос должен быть:
$posts_of_class_of_user =
RegisteredStudent::where('user_id',$user->id)->first()->classroom->posts;
Сначала это приведет к получению зарегистрированного пользователя из RegisteredStudent, а затем он получит экземпляр Classroom из relatationsto relatation, а затем получит все связанные posts
с hasMany отношения.
Обратите внимание, что, используя отношение, вы можете избежать сложных запросов, особенно в вашем случае. Вам не нужен какой-либо сложный запрос. Просто используйте красноречивый реляционный подход.
Комментарии:
1. Он выдает сообщение «Свойство [класс] не существует в экземпляре Eloquent builder».
2. opps, просто
->first()
отсутствует перед классом. обновляю свой ответ сейчас3. RegisteredStudent не имеет прямого отношения к Post. поэтому
->posts
предполагается, что он выдает ошибку. Это может сработать, если вы создадите отношение ‘hasManyThrough` в модели. @Psycho4. то, о чем вы говорите, — это прямой доступ к сообщениям без классной
RegisteredStudent::where('user_id',$user->id)->first()->posts
комнаты, который выполняется с помощью hasManyThrough, но я получаю доступ, какclassroom->posts