英文:
eloquent laravel parameter argument
问题
To fix the error and display the product brand by the parameter argument, you can make the following changes to your ProductController.php
:
Replace this block of code:
$query->Select::where('id', $brand)
->whereIn(['id' => $brand]);
With this code:
$query->whereIn('id', Select::where('brand_id', $brand)->pluck('product_id'));
This modification will correctly filter products based on the selected brand and resolve the error you mentioned.
英文:
I am trying to display a parameter argument in the URL address for my products. For example: /product?brand=2&view=5
This address is divided into two parts:
- The brand
- The number of product in display
products
table (model name: Product
)
id | title |
---|---|
1 | iPhoneX |
2 | SamsungNote8 |
3 | MiRedmi8 |
4 | MiPoco5 |
5 | MiX3Pro |
6 | SonyZ2 |
7 | MiX5Pro |
8 | MiX4Pro |
9 | MiX7Pro |
brands
table (model name: Brand
)
id | name |
---|---|
1 | Sony |
2 | Mi |
3 | LG |
4 | Samsung |
5 | iPhone |
selects
table (model name: Select
)
product_id | brand_id |
---|---|
1 | 5 |
2 | 4 |
3 | 2 |
4 | 2 |
5 | 2 |
6 | 1 |
7 | 2 |
8 | 2 |
9 | 2 |
I want the product brand to be displayed by the parameter argument.
out: /product?brand=2&view=5
3: MiRedmi8
4: MiPoco5
5: MiX3Pro
7: MiX5Pro
8: MiX4Pro
routes/web.php
Route::get('/product', 'ProductController@index');
app/Models/Product.php
class Product extends Model
{
public $timestamps = false;
}
app/Models/Brand.php
class Brand extends Model
{
public $timestamps = false;
}
app/Models/Select.php
class Select extends Model
{
public $timestamps = false;
}
app/Http/Controllers/ProductController.php
public function index()
{
$view = request()->view ? request()->view : 20;
$products = Product::orderBy('id', 'DESC')
->where(function($query) {
$brand = Request()->brand;
if ($brand) {
$query->Select::where('id', $brand)
->whereIn(['id' => $brand]);
}
})
->paginate($view);
return view('index', compact('products'));
}
resources/views/index.blade.php
@foreach($products as $row)
{{ $row->id }} : {{ $row->title }}
@endforeach
{{ $products->appends(request()->query())->links() }}
But it gives me an error saying that Select
does not exist:
> Property [Select] does not exist on the Eloquent builder instance.
How do I fix this error and display the product brand by the parameter argument?
答案1
得分: 1
你的数据库布局没有意义,如果一个 Product
关联一个 Brand
,那么不需要使用中间表。相反,你的 products
表应该有一个 brand_id
列。
然而,根据你现在的结构,第一步是实际定义你的关联关系:
class Product extends Model
{
public $timestamps = false;
public function brands() {
return $this->hasMany(Brand::class);
}
}
class Brand extends Model
{
public $timestamps = false;
public function products() {
return $this->hasMany(Product::class);
}
}
你的 Select
模型是一个中间模型。它可能甚至不需要是一个模型,但如果需要,它应该被定义为一个 Pivot
,而不是一个 Model
:
use Illuminate\Database\Eloquent\Relations\Pivot;
class Select extends Pivot
{
public $timestamps = false;
public function brand() {
return $this->belongsTo(Brand::class, 'brand_id');
}
public function product() {
return $this->belongsTo(Product::class, 'product_id');
}
}
然后,我认为你的控制器应该如下所示。Builder::when()
根据其第一个参数的值执行条件查询。因此,如果查询字符串变量被填充,它将搜索和过滤关联以获取适当的值。请注意,request()->query()
是用于获取查询字符串变量的方法:
public function index()
{
$view = request()->query("view", 20);
$products = Product::orderBy("id")
->when(
request()->query("brand"),
function ($query) {
$brand = request()->query("brand");
$query
->with(["brands" => fn ($q) => $q->where("id", $brand)])
->whereHas("brands", fn ($q) => $q->where("id", $brand));
},
function ($query) {
$query->with("brands");
}
)
->paginate($view);
return view('index', compact('products'));
}
英文:
Your database layout makes no sense, if a Product
has one Brand
then a pivot table is not needed. Your products
table should instead have a brand_id
column.
However, working with what you have now, step one is to actually define your relationships:
class Product extends Model
{
public $timestamps = false;
public function brands() {
return $this->hasMany(Brand::class);
}
}
class Brand extends Model
{
public $timestamps = false;
public function products() {
return $this->hasMany(Product::class);
}
}
Your Select
model is a pivot model. It probably doesn't even need to be a model, but if it is, it should be defined as a Pivot
not a Model
:
use Illuminate\Database\Eloquent\Relations\Pivot;
class Select extends Pivot
{
public $timestamps = false;
public function brand() {
return $this->belongsTo(Brand::class, relation: __FUNCTION__);
}
public function product() {
return $this->belongsTo(Product::class, relation: __FUNCTION__);
}
}
Then I think your controller would look like this. Builder::when()
executes a conditional query based on the value of its first argument. So if the query string variable is filled it will search and filter the relationship for an appropriate value. Note request()->query()
is how you get query string variables.
public function index()
{
$view = request()->query("view", 20);
$products = Product::orderBy("id")
->when(
request()->query("brand"),
function ($query) {
$brand = request()->query("brand");
$query
->with(["brands", fn ($q) => $q->where("id", $brand])
->whereHas("brands", fn ($q) => $q->where("id", $brand);
},
function ($query) {
$query->with("brands");
}
)
->paginate($view);
return view('index', compact('products'));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论