I have fields defined as the following for a resource in Nova:
Select::make('Type')
->options([
'video' => 'Video',
'download' => 'Download',
])
->rules('required'),
File::make('File', 'file_name')
->disk('local')
->path('/files')
I am trying to setup different validation rules for the File field depending on the value of the type field. For example where the type is download accept document mimes and a max size of 1mb, whilst if set as video accept video file mimes and max size of 30mb.
I haven't really got anywhere with trying to achieve this.
I've looked through the docs and neither validation rule objects or custom closure rules will help me as I wont be able to access the value of the type field from them.
Similarly, I thought of extending the NovaRequest object as one might do with a FormRequest, but this wouldn't do the front-end validation that Nova applies.
Is there any way to achieve this that I'm missing?
I now have this working through the tutorial provided here from John Beales who is similarly complaining that Nova doesn't pick up on Laravel Form Requests automatically.
1: Create a Request for the Nova Resource that extends FormRequest:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class StoreResourceRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
// Users authorized to make the request are:
// - users updating themselves.
// - staff
// - guests creating a new user.
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = self::ruleGetter($this);
if(empty($this->user())) {
$rules = array_merge_recursive($rules, self::creationRuleGetter($this));
} else {
$rules = array_merge_recursive($rules, self::updateRuleGetter($this));
}
return $rules;
}
public static function ruleGetter( $request, $rule = null ) {
$rules = [
'type' => ['required',Rule::in(['video', 'download'])],
];
if($request['type'] == 'download'){
$rules['file_name'] = ['required','mimes:jpeg,png,jpg,doc,docx,pdf','max:1000'];
}
if($request['type'] == 'video'){
$rules['file_name'] = ['required','mimes:mp4','max:50000'];
}
if(!empty($rule)) {
if(isset($rules[$rule])) {
return $rules[$rule];
}
return '';
}
return $rules;
}
public static function creationRuleGetter( $request, $rule = null ) {
$rules = [
];
if(!empty($rule)) {
if(isset($rules[$rule])) {
return $rules[$rule];
}
return '';
}
return $rules;
}
public static function updateRuleGetter( $request, $rule = null ) {
$rules = [
];
if(!empty($rule)) {
if(isset($rules[$rule])) {
return $rules[$rule];
}
return '';
}
return $rules;
}
}
2: Update Nova Resource to load these rules:
namespace App\Nova;
use App\Http\Requests\StoreResourceRequest;
//...
public function fields(Request $request)
{
return [
//...
Select::make('Type')
->options([
'video' => 'Video',
'download' => 'Download',
])
->rules(StoreResourceRequest::ruleGetter($request, 'type')),
File::make('File', 'file_name')
->rules(StoreResourceRequest::ruleGetter($request, 'file_name'))
];
}
The above works for both types of validation and stores the correct value in the database. Nova can interact with the file normally.
It's just a pity this isn't built in to Nova and the validation logic has to be duplicated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With