laravel - Laravel,简单而正确的关系方式
问题描述
我想用这个逻辑列出相关品牌的相关类别。
产品表
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();
});
}
网页.php
Route::get('{Brand}/{Category}/{Product}', 'ProductsController@show');
Route::get('{Brand}/{Category}', 'ProductsController@index');
例如,第一条路线;Samsung/phones 应列出所有带有以下代码部分的三星手机。还有其他方法可以使这些代码变得简单吗?并且此查询返回 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'));
}
}
产品.php
class Product extends Model
{
public function brands()
{
return $this->belongsTo('App\Brand');
}
public function categories()
{
return $this->belongsTo('App\Category');
}
}
分类.php
class Category extends Model
{
public function brands()
{
return $this->belongsToMany('App\Brand');
}
public function products()
{
return $this->hasMany('App\Product');
}
}
解决方案
首先阅读有关 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 参数是 slugs 而不是 ids,因此自动路由模型绑定将不起作用。带有蛞蝓的更新解决方案:
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);
推荐阅读
- php - 如何在 php 中正确创建唯一令牌?
- javascript - 切换后css模态不显示onclick
- python - Google doc API 无法找到父文件夹
- python - SQLAlchemy中具有最大值的三个表连接
- scala - yyyy-MM-dd HH24:mm:ss 时间戳使用 Spark SQL
- cron - crontab:简单的作业没有运行
- .net - 无法在 docker 映像中运行 PlayWright
- c# - 应用服务 - 从字节 [] 创建 X509 证书时磁盘空间不足
- google-data-studio - Google Data Studio URL 参数 iframe embed - 在新标签页中打开时丢弃的 URL 参数
- windows-10 - USB A 到 A 连接 - 笔记本电脑可以看到 Surface 平板电脑,但 Surface 看不到笔记本电脑