【问题标题】:laravel 5.4 duplicates of queries within a nested foreach looplaravel 5.4嵌套foreach循环中的查询重复
【发布时间】:2017-09-17 05:19:48
【问题描述】:

在我的 Laravel 5.4 项目中,我试图从模型文章和状态之间的关系中获取一些数据。关系类型是 OneToMany,其中文章有一个状态,状态有许多文章。

为了获取想要的数据,我在 whereHas() 方法的帮助下遍历模型文章项目的集合,这些项目与模型/关系状态一起被 eagerLoaded。第一次迭代构建了一个正确的查询,但每次迭代它都会附加由方法whereHas() [这是我的猜测] 生成的查询。

如果给定,我该如何解决这个问题(?) ->

文章型号:

class Article extends Model
{  
 public function status()
 {
    return $this->belongsTo(ArticleStatus::class,'articleStatus_id');
 }
}

状态模型:

class ArticleStatus extends Model
{
 public function article()
 {
    return $this->hasMany(Article::class);
 }
}

通过 Controller 将变量传递给视图:

class RedactionController extends Controller
{
 /**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index()
{
    $articles = Auth::user()->articles();
    $statuses = array_values(ArticleStatus::all()->pluck('status')->toArray());     

    return view('redaction',[
            'articles' => $articles,
            'statuses' => $statuses,
        ]);
}

我想要遍历数据并显示它们对应于文章状态的视图的一部分:

<div class="tab-content">
            @foreach($statuses as $count => $status)

                    <div class="card-block tab-pane @if($count==0) active @endif" id="{{$status}}">
                        <table class="table">
                            <thead>
                                <tr>
                                    <th>#</th>
                                    <th>Titulok</th>
                                    <th>Vytvorené</th>
                                    <th>Publikované</th>
                                    <th>Upravené</th>
                                    <th class="text-center">Action</th>
                                </tr>
                            </thead>
                            <tbody>

                            <p class="mt-5"><b>{{$status}}</b></p>

                            @php 
                                $result = $articles->with('status')->whereHas('status', function ($query) use ($status)
                         {                                                                        
                           $query->where('status','=', $status);
                         })->toSql();   

                                echo $result;           
                            @endphp 
                          </tbody>
                        </table>
                    </div>

            @endforeach
            </div>

以 $result 变量形式回显的结果:

第一次迭代:

select * from `articles` where `articles`.`user_id` = ? and `articles`.`user_id` is not null and exists (select * from `article_statuses` where `articles`.`articleStatus_id` = `article_statuses`.`id` and `status` = ?)

第二次迭代:

select * from `articles` where `articles`.`user_id` = ? and `articles`.`user_id` is not null and exists (select * from `article_statuses` where `articles`.`articleStatus_id` = `article_statuses`.`id` and `status` = ?) and exists (select * from `article_statuses` where `articles`.`articleStatus_id` = `article_statuses`.`id` and `status` = ?)

第三次迭代:

select * from `articles` where `articles`.`user_id` = ? and `articles`.`user_id` is not null and exists (select * from `article_statuses` where `articles`.`articleStatus_id` = `article_statuses`.`id` and `status` = ?) and exists (select * from `article_statuses` where `articles`.`articleStatus_id` = `article_statuses`.`id` and `status` = ?) and exists (select * from `article_statuses` where `articles`.`articleStatus_id` = `article_statuses`.`id` and `status` = ?)

因此,查询构建了每个 foreach 迭代,并在前一个迭代的末尾附加了一些查询。如果您能给我一些建议,我将不胜感激。

谢谢

【问题讨论】:

    标签: php mysql laravel foreach laravel-5.4


    【解决方案1】:

    您必须从 foreach 中取出查询并将其放入您的索引函数中,例如

    $results = $articles->with('status')->whereHas('status', function ($query) use ($statuses)
                         {                                                                        
                           $query->whereIn('status', $statuses);
                         })->get();
    

    这将获取所有在$statuses 中具有所有状态的文章,然后您可以为您的视图创建一个结构,例如

    $final_results = [];
    foreach($results as $article)
    {
        if( ! isset($final_results[$article->status->status]))
            $final_results[$article->status->status] = [];
    
        $final_results[$article->status->status][] = $article;
    }
    

    这样你就有了一个数组,其属性状态为 ArticleStatus 作为文章的键,将 $final_results 变量传递给你的视图。

    那么在你看来

    <div class="tab-content">
            @foreach($final_results as $status => $articles)
    
    
                    <div class="card-block tab-pane @if($count==0) active @endif" id="{{$status}}">
                        <table class="table">
                            <thead>
                                <tr>
                                    <th>#</th>
                                    <th>Titulok</th>
                                    <th>Vytvorené</th>
                                    <th>Publikované</th>
                                    <th>Upravené</th>
                                    <th class="text-center">Action</th>
                                </tr>
                            </thead>
                            <tbody>
    
                            <p class="mt-5"><b>{{$status}}</b></p>
                             @foreach($articles as $article)
                           // Here your code to show Article properties
                             @endforeach
                          </tbody>
                        </table>
                    </div>
    
            @endforeach
            </div>
    

    【讨论】:

    • 您好,非常感谢您的解决方案,它工作正常。只是为了记录,$count 变量必须被删除,因为它没有被声明并被替换,例如 $loop->index (laravel 的变量)..
    猜你喜欢
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多