【问题标题】:Retrieve Models with invalid Category Subcategory relations检索具有无效类别子类别关系的模型
【发布时间】:2019-11-28 13:46:52
【问题描述】:

我有三个模型RecordCategorySubcategory。 Record 表将 category_id 和 subcategory_id 存储为外键。有一个数据透视表“category_subcategory”。

我想通过模型中的自定义函数以优雅且高效的方式检索具有“无效的类别子类别关系”的所有记录。

无效的类别子类别关系”是什么意思:

  • a) 记录具有类别和子类别。但子类别不属于类别(数据透视表中没有条目)
  • b) 记录有一个类别但没有子类别(subcategory_id = NULL)。因为Category本身有Subcategories,所以Record的subcategory_id应该为NULL
  • c) Record有Category和Subcategory,但是Cateory本身没有Subcategories,因此Record应该有subcategory_id = NULL

通过模型中的这个自定义函数,我希望能够在控制器中做这样的事情:

Records::withInvalidCategorySubcategoryRelation()->get(); //or similar 

而不是像在 Controller 中那样经历无穷无尽的 foreach 循环

$records = Record::all();
foreach($records as record){ ...

非常感谢任何建议!

这是我的模型类:

class Record extends Model
{
    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    public function subcategory()
    {
        return $this->belongsTo(Subcategory::class);
    }

}
class Category extends Model
{

    public function subcategories()
    {
        return $this->belongsToMany(Subcategory::class);
    }

}
class Subcategory extends Model
{

    public function categories()
    {
        return $this->belongsToMany(Category::class);
    }
}

【问题讨论】:

    标签: laravel eloquent model pivot-table


    【解决方案1】:

    感谢@Zeshan Khattak,我能够得到我需要的东西。现在我得到满足 a) b) c) 的“无效”记录

        public function scopeInvalidRecords($query)
    {
    
        return $query->whereExists(function($q) {
            $q->select(\DB::raw(1))
            ->from('category_subcategory')
            ->whereRaw('
                category_subcategory.category_id = records.category_id
            ');
            })->whereNotExists(function($q) {
                $q->select(\DB::raw(1))
                ->from('category_subcategory')
                ->whereRaw('
                    category_subcategory.category_id = records.category_id
                    AND
                    category_subcategory.subcategory_id = records.subcategory_id
                ');
                })->orWhereNotExists(function($q) {
                    $q->select(\DB::raw(1))
                    ->from('category_subcategory')
                    ->whereRaw('
                        category_subcategory.category_id = records.category_id
                    ');
                    })->whereNotNull('subcategory_id');
    }
    

    【讨论】:

      【解决方案2】:

      Laravel 提供了whereNotExists,在这里可能会有所帮助。

      Record模型中添加如下函数:

      // Adjust the func name as per your test ;)
      public function scopeInvalidRecords($query)
      {
          return $query->whereNotExists(function($q) {
              $q->select(\DB::raw(1))
                 ->from('category_subcategory')
                 ->whereRaw('
                    category_subcategory.category_id = records.category_id 
                    AND 
                    category_subcategory.subcategory_id = records.subcategory_id
                 ');
          });
      }
      
      

      在控制器中:

      Record::invalidRecords()->get();
      // It'll give you all the invalid records(invalid as per your definition)
      

      希望对你有帮助!

      【讨论】:

      • 非常感谢您的建议!你基本上回答了我的要求。但我发现我对无效记录与有效记录的定义并不精确。我已经更新了上面的描述。如果您可以扩展 Model 函数以同时考虑 b) 和 c),那就太好了。干杯蒂姆
      • 由于@Zeshan Khattak 给出了决定性的提示并且是最有帮助的,我将他的回答标记为正确。由于我没有充分描述我的要求并随后对其进行了扩展,因此我列出了我的最终解决方案,该解决方案有效并满足我在下面的答案中更新的要求。
      猜你喜欢
      • 2012-08-21
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 2011-12-07
      • 1970-01-01
      相关资源
      最近更新 更多