gpt4 book ai didi

php - Laravel 嵌套预加载约束

转载 作者:行者123 更新时间:2023-12-01 06:22:17 32 4
gpt4 key购买 nike

我有一个问题 Eloquent 模型,一个类(class) Eloquent 模型,一个大学 Eloquent 模型。大学和类(class)之间存在一对多的关系。问题和类(class)之间存在多对多关系。三种型号如下图所示:

问题模型

namespace App;
use Illuminate\Database\Eloquent\Model;
class Question extends Model
{
/**
* The database table that the Model uses
* @var string
*/
protected $table = "questions";

/**
* The fields that are mass assignable
* @var array
*/
protected $fillable = ['title','body','images','quality_score','deactivated','creator_id','reviewer_id'];


/**
* Images is stored as serialized json.
* So we cast it to a PHP array.
* See: http://laravel.com/docs/5.1/eloquent-mutators#attribute-casting
*/
protected $casts = [
'images' => 'array',
];

public function courses(){
return $this->belongsToMany('App\Course');
}
}

类(class)模式
namespace App;

use Illuminate\Database\Eloquent\Model;

class Course extends Model
{
/**
* The database table used by the model
* @var string
*/
protected $table = "courses";

/**
* The fields that can be mass assigned
* @var array
*/
protected $fillable = ['name', 'instructor', 'acronym', 'university_id', 'creator_id', 'reviewer_id'];

/**
* There exists a many to one relationship between the Course and User
* This user is the creator of the course
*
* @method void
*
*/
public function creator(){
return $this->hasOne('App\User','creator_id');
}

/**
* There exists a many to one relationship between the Course and User
* This user is the reviewer of the course
* The reviewer of the Course will always be an admin
* If an Admin is the creator, then the reviewer is also the same admin
*
* @method void
*/

public function reviewer(){
return $this->hasOne('App\User','reviewer_id');
}

/**
* There exists a one to many relationship between the University and the Course
* This university is where the course is held
* Courses may float i.e. not be associated to any university
*
* @method void
*/
public function university(){
return $this->belongsTo('App\University');
}

/**
* This method is an accessor. It automatically changes the acronym to be all capitals
* regardless of how it is stored in the database.
* See: http://laravel.com/docs/5.1/eloquent-mutators#accessors-and-mutators
* @param $value (String from Database)
* @return string (Capitalized String)
*/
public function getAcronymAttribute($value){
return strtoupper($value);
}
}

大学模式
namespace App;

use Illuminate\Database\Eloquent\Model;

class University extends Model
{
/**
* The database table used by the model
* @var string
*/
protected $table = "universities";

/**
* The fields that can be mass assigned
* name = Name of the University (Example: University of Illinois at Urbana Champaign)
* acronym = Acronym of the University (Example: UIUC)
* creator_id = Id of User that created the University
* reviewer_id = Id of User that reviewed and approved the University
*
* Universities will not be displayed to users without admin role unless they have been reviewed.
*
* @var array
*/
protected $fillable = ['name','acronym','creator_id','reviewer_id'];

/**
* This method is an accessor. It automatically changes the acronym to be all capitals
* regardless of how it is stored in the database.
* See: http://laravel.com/docs/5.1/eloquent-mutators#accessors-and-mutators
* @param $value (String from Database)
* @return string (Capitalized String)
*/
public function getAcronymAttribute($value){
return strtoupper($value);
}

}

在我的主页上,我显示了一个问题列表,并允许对类(class)和大学进行过滤。 Controller 方法如下所示:
public function getHome(Request $request){

/**
* Eager Load with Course and University
*/
$questions = Question::with('courses.university')->get();

/*
* Filter Questions to remove unwanted entries based on course id
*/
if($request->has('course_id') && $request->input('course_id') != -1){
$questions = $questions->filter(function($question) use ($request){
foreach($question->courses as $course){
if ($course->id == $request->input('course_id')){
return true;
}
}
});
}

/*
* Filter Questions to remove unwanted entries based on university id
*/
if($request->has('university_id') && $request->input('university_id') != -1){
$questions = $questions->filter(function($question) use ($request){
foreach($question->courses as $course){
if ($course->university->id == $request->input('university_id')){
return true;
}
}
});
}

/*
* Return the Welcome View with Pagination on the Questions Displayed
* List of Courses and List of Universities
*/
return view('welcome',[
'questions' => $questions,
'courses' => Course::all(),
'universities' => University::all(),
'selected_university_id' => $request->input('university_id',-1),
'selected_course_id' => $request->input('course_id',-1)
]);

}

我在上面所做的是从数据库中返回所有问题,然后他们将它们组合起来以删除所有与过滤器不匹配的问题。这显然是非常低效的。我想使用带有约束的嵌套急切加载,除非我在定义约束的样子时遇到了很多麻烦。此外,我想使用服务器端分页来使客户端在较低速度的互联网连接上体验更好。

这是我的尝试之一:
$questions = Question::with(['courses.university' => function($query) use ($request){
if($request->has('university_id') && $request->input('university_id') != -1) {
$query->where('id', $request->input('university_id'));
}

if($request->has('course_id') && $request->input('course_id') != -1){
$query->where('courses.id',$request->input('course_id'));
}
}])->paginate(10);

当我没有任何过滤器时,这很好用。

当我定义了一个 university_id 时,我收到错误:试图获取非对象的属性( View :/var/www/testing.com/resources/views/welcome.blade.php)

当我定义了 course_id 时,我收到错误:SQLSTATE[42S22]: Column not found: 1054 Unknown column 'courses.id' in 'where clause' (SQL: select * from universities where universities . id in ( 2) 和 courses . id = 1)

当我定义了 course_id 时,我预计会出现错误(因为我在 $query->where 方法的第一个参数处进行了盲刺。

我正在寻找帮助定义嵌套的急切加载约束。

最佳答案

我在一篇中等文章中找到了解决方案。该解决方案适用于 Laravel 的更高版本,因为它使用 哪里有 .

// If you want to put the constraint on the second relation
$questions = Question::with(['courses' => function($query) use($request){
return $query->whereHas('university', function($inner_query) use($request){
return $inner_query->where('id', $request->input('university_id'));
});
}, 'courses.university'])->paginate(10);

对于您的情况,一个简单的 whereHas 应该可以解决问题。
$questions = Question::whereHas('courses', function($query) use ($request){
return $query->where('university_id', $request->input('university_id'));
})->with(['courses.university'])->paginate(10);

我还建议使用 when 子句来减少代码量。
$questions = Question::when(($request->has('course_id') && $request->input('course_id') != -1), function ($query) use($request){
return $query->where('course_id', $request->input('course_id'));
})->when($request->has('university_id') && $request->input('university_id') != -1, function ($outer_query) use($request){
return $outer_query->whereHas('courses', function($query) use($request){
return $query->where('university_id', $request->input('university_id'));
})->with(['courses.university']);
})->with(['courses.university'])->paginate(10);

关于php - Laravel 嵌套预加载约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32174121/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com