Laravel,简单而正确的关系方式

时间:2019-01-08 10:43:49

标签: laravel eloquent

我想用这种逻辑列出相关品牌的相关类别。

产品表

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('slug');
        $table->integer('brand_id')->unsigned();
        $table->foreign('brand_id')->references('id')->on('brands')->onDelete('cascade');
        $table->integer('category_id')->unsigned();
        $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
        $table->timestamps();
    });
}

web.php

Route::get('{Brand}/{Category}/{Product}', 'ProductsController@show');
Route::get('{Brand}/{Category}', 'ProductsController@index');
例如,

第一条路线;三星/电话应列出以下所有三星电话及其代码部分。还有另一种方法可以使这些代码变得简单吗?并且此查询返回null。我检查查询是否获得正确的列,但返回null。

use App\Product;
use App\Brand;
use App\Category;

class ProductsController extends Controller
{
    public function index(Request $request)
    {   
        $category = $request->Category;
        $cat_id = Category::select('id')
                    ->where('slug',$category)
                    ->get();

        $brand = $request->Brand;
        $br_id = Brand::select('id')
                ->where('slug', $brand)
                ->get();

        $products = Product::select('id','name','slug')
                ->where('category_id', $cat_id)
                ->where('brand_id', $br_id)
                ->get();

        return view('products.index', compact('products'));
    }
}

Product.php

class Product extends Model
    {
        public function brands()
        {
            return $this->belongsTo('App\Brand');
        }

        public function categories()
        {
            return $this->belongsTo('App\Category');
        }
    }

Category.php

class Category extends Model
{

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

    public function products()
    {
        return $this->hasMany('App\Product');
    }
}

3 个答案:

答案 0 :(得分:0)

首先阅读有关laravel关系的文档: https://laravel.com/docs/5.7/eloquent-relationships

当前代码不起作用的原因是因为在您的路线中要求输入参数:

Route::get('{Brand}/{Category}', 'ProductsController@index');

但是在ProductsController的index()方法中,您没有包含这些参数。

 public function index(Request $request, Brand $brand, Category $category)

代码中的第二个问题是您根本没有使用关系。您当前的控制器只是进行了一次雄辩的新查询。

使用类别模型中定义的方法获取给定类别的所有产品的示例:

public function index(Request $request, Brand $brand, Category $category)
{   

    $products = $category->products;

    return view('products.index', compact('products'));
}

使用指定品牌扩展此示例:

public function index(Request $request, Brand $brand, Category $category)
{   

    $products = $category->products()->where('brand_id', $brand->id)->get();

    return view('products.index', compact('products'));
}

更新

如评论中所述,URL参数是段符而不是id,因此自动路由模型绑定将不起作用。弹头的更新解决方案:

public function index(Request $request, $brand, $category)
{
    $categoryModel = Category::where('slug', $category)->firstOrFail();
    $brandModel = Brand::where('slug', $brand)->firstOrFail();   

    $products = $categoryModel->products()->where('brand_id', $brandModel->id)->get();

    return view('products.index', compact('products'));
}

进一步改进代码将是添加作用域或辅助方法,以便您可以执行类似Brand::FindBySlug($slug);的操作

答案 1 :(得分:0)

我认为您最后使用的是get方法,这不仅会给您数组一个值。您可以尝试以下代码吗?这可能有帮助

use App\Product;
use App\Brand;
use App\Category;

class ProductsController extends Controller
{
public function index(Request $request)
{   
    $category = $request->Category;
    $cat_id = Category::where('slug',$category)->value('id);

    $brand = $request->Brand;
    $br_id = Brand::where('slug', $brand)->value('id);

    $products = Product::select('id','name','slug')
            ->where('category_id', $cat_id)
            ->where('brand_id', $br_id)
            ->get();

    return view('products.index', compact('products'));
}
}

答案 2 :(得分:0)

您应该尝试以下操作:

public function index($brand, $category,Request $request)
    {   

        $products = Product::select('id','name','slug')
                ->where('category_id', $category)
                ->where('brand_id', $brand)
                ->get();

        return view('products.index', compact('products'));
    }