サブクエリ

商品分類は、階層になるように設計。
3階層を限度としている。

しかし、2階層目で下位の階層がないものもあり得る。
もちろん1階層目でもそうだけど、そもそもそういう分類は考え直した方がよいと思う。

商品は複数の商品分類を登録できるけれども、登録できる商品分類は最下位のもの、というルールを設けた。

最下位の商品分類だけを取り出すにはどうしたらよいか。

サブクエリを使えば可能。category_idが親分類コードとする。

select * from category A where A.id NOT in 
(select B.category_id from category B where b.category_id is not null)

なので、データベースにサブクエリを使用したビューを作って、それを使うように登録したモデルを作成してみたらうまく動作した。

しかし、Controllerのアクション内で、(Eloquentの範囲で)サブクエリをどう書くのかやってみた。
あまり良い書き方ではないようだが、とりあえず動作はしました。

public function create()
    {
        $products = Product::all()->sortBy("id");
        $categories = Category::all()->sortBy("hierarchy");
        $q_categories = Category::whereNotIn('id',function($query){
            $query -> select('category_id')
                -> from (with(new Category)-> getTable()) 
                -> whereNotNull('category_id');
        })->get()->sortBy("hierarchy");
        return view('product_category_categorizations.create',compact('products','categories','q_categories'));
    }