验证表单中公开的主键/外键是否完整

时间:2017-11-13 11:54:29

标签: php mysql laravel laravel-5

我有一份调查表。每个问题都有3-4个预定义的答案作为单选按钮。单选按钮的值是数据库中答案的主键。

由于所有问题的所有答案都存储在一个表中,如果用户增加该值,则该ID可能仍然是有效的外键,但它不属于该问题。

确保不操作单选按钮的值的最佳做法是什么?

3 个答案:

答案 0 :(得分:2)

在您的控制器中,您可以执行以下操作:

# Get the ids of the answers that are valid for that question
$validAnswerIds = $Question->answers->pluck('id')->toArray();

# Validate that the answer given is in there
$rules = ['answer' => Rule::in( $validAnswerIds ) ];
$request->validate( $rules );

答案 1 :(得分:2)

作为David has already mentioned,您需要验证您的业务逻辑。

最多" laravelish"方式,如you mentioned,是在请求类中执行验证,并在需要时开发额外的验证器扩展。使用验证逻辑乱丢控制器,如Erin has mentioned,根本不是一个好习惯;它虽然有效。

我假设您有两个单独的模型:QuestionAnswer。此外,他们之间设置了完整的1-N关系,问题可能有很多答案,每个答案都属于一个问题:

class Question extends Model
{
    public function answers()
    {
        return $this->hasMany(Answer::class);
    }
}

class Answer extends Model
{
    public function question()
    {
        return $this->belongsTo(Question::class);
    }
}

我们假设您还有SurveyController

class SurveyController extends Controller
{
    public function store(CreateSurveyRequest $request)
    {
        // Request is validated by now and you can be sure that the 
        // answer belongs to the question. Go on and create/store 
        // the Survey entity.
    }
}

进行实际数据验证的请求类:

class CreateSurveyRequest extends FormRequest
{
    public function rules()
    {
        // Assuming the request contains `answer_id` and `question_id` fields:

        return [
            'answer_id' => 'exists:answers,id,question_id,' . request('question_id'),
            // e.g. 
            // 8 => 'exists:answers,id,question_id,10'
            // Which loosly translates to "answer ID 8 should belong to question ID 10"
        ];
    }
}

这样的exists规则定义确保答案记录在questions表上有一个外键,因此它是该问题的有效答案。

重点是Laravel的exists规则supports additional conditions。有意思的是,提交提案的人感觉与你在这里的需要完全一样。

答案 2 :(得分:1)

  

确保无法操纵radiobutton的值

你不能,这是错误的做法。 始终假设客户端信息可以被操纵。

相反,验证对服务器发出的请求的业务逻辑。当您的服务器端代码收到一组提交的问题和答案时,请根据您提供的数据验证所提交的数据是否有效。

这可以通过先查询数据库,执行验证逻辑,然后保存数据来完成。可以通过创建存储过程或其他数据库端逻辑来确保有效数据,然后只与数据库交互一次。等等。无论哪种方式,您都可以定义和验证系统中规定的业务规则。