php Laravel 9查询生成器where子句的模型ID为空

gv8xihay  于 2023-01-19  发布在  PHP
关注(0)|答案(1)|浏览(118)

我正在处理一个Laravel 9项目,并创建了一个名为ValidModelOwnership的自定义验证规则,该规则应该根据传递给它的一些值来检查用户试图添加的字段是否属于某个模型。
我写了规则,但是调试输出$model->toSql()的时候id是空的?
我错过了什么?
我的规则:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\Log;

class ValidModelOwnership implements Rule
{
    /**
     * The model we're checking
     */
    protected $model;

    /**
     * Array of ownership keys
     */
    protected $ownershipKeys;

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct($model, $ownershipKeys)
    {
        $this->model = $model;
        $this->ownershipKeys = $ownershipKeys;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $model = $this->model::query();
        $model = $model->where($this->ownershipKeys);

        Log::debug($model->toSql());

        if (!$model->exists()) {
            return false;
        }

        return true;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return "The :attribute field doesn't belong to you and/or your company.";
    }
}

以及我在控制器中的用法:

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store($company_id, $buyer_id, Request $request)
{
    $this->authorize('create', BuyerTier::class);

    $validator = Validator::make($request->all(), [
        'name' => [
            'required',
            'string',
            Rule::unique(BuyerTier::class)
                ->where('buyer_id', $buyer_id)
                ->where('company_id', $company_id)
        ],
        'country_id' => [
            'required',
            'numeric',
            new ValidModelOwnership(Country::class, [
                ['company_id', 80]
            ])
        ],
        'product_id' => [
            'required',
            'numeric',
            new ValidModelOwnership(Product::class, [
                ['company_id', 80]
            ])
        ],
        'processing_class' => 'required|string',
        'is_default' => [
            'required',
            'boolean',
            new ValidDefaultModel(BuyerTier::class, $buyer_id)
        ],
        'is_enabled' => 'required|boolean'
    ]);

    if ($validator->fails()) {
        return response()->json([
            'message' => 'One or more fields has been missed or is invalid.',
            'errors' => $validator->messages(),
        ], 400);
    }

    try {
        $tier = new BuyerTier;
        $tier->user_id = Auth::id();
        $tier->company_id = $company_id;
        $tier->buyer_id = $buyer_id;
        $tier->country_id = $request->input('country_id');
        $tier->product_id = $request->input('product_id');
        $tier->name = trim($request->input('name'));
        $tier->description = $request->input('description') ?? null;
        $tier->processing_class = $request->input('processing_class');
        $tier->is_default = $request->boolean('is_default');
        $tier->is_enabled = $request->boolean('is_enabled');
        $tier->save();

        return response()->json([
            'message' => 'Buyer tier has been created successfully',
            'tier' => $tier
        ], 201);
    } catch (\Exception $e) {
        return response()->json([
            'message' => $e->getMessage()
        ], 400);
    }
}

我已经硬编码了我的id,以说明即使静态设置,它也不会被传递:
[2023 - 01 - 19 09:40:59]本地调试:从products中选择 *,其中(company_id =?)和productsdeleted_at为空

qxsslcnc

qxsslcnc1#

Laravel(以及大多数其他框架)在构建SQL查询时提取出变量,以防止SQL注入。
所以下面这个问题很有说服力:

User::where('name', 'Larry');

将变为:

SELECT * FROM `users` WHERE `name` = ?

它还将传递一个 bindings 数组:['Larry']。当SQL处理查询时,它用绑定中的值替换?
因此,如果您想查看完整的查询,则需要记录SQL * 和 * 绑定:

Log::debug($model->toSql());
Log::debug($model->getBindings());

相关问题