优美的Laravel参数参数

huangapple go评论65阅读模式
英文:

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'));
}

huangapple
  • 本文由 发表于 2023年6月29日 20:41:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76581168.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定