nova-belongsto-depend icon indicating copy to clipboard operation
nova-belongsto-depend copied to clipboard

Leverage nova resources relatableQuery

Open marcorivm opened this issue 6 years ago • 1 comments

Nova already provides a method to help scope belongsTo queries, I think it would be a good idea to use that relatableQuery to hydrate the BelongsTo relationship plus our own queries. I'm doing something like this on some resources:

NovaBelongsToDepend::make(__('School'), 'school', School::class)
                ->options(School::relatableQuery($request, \App\School::query())->get()),

This allows the scoping code to be written in one place only and used across "native" nova fields and custom fields like this one.

marcorivm avatar Nov 15 '18 20:11 marcorivm

Very nice tip, but it seems options is loaded once for all. Consider this situation:


public function fields(Request $request)
    {
        $fields = [];
		$fields[] = MorphTo::make(__("questionable"),'questionable')->types([
			\App\Nova\Patient::class,
			\App\Nova\Caregiver::class,
		])
			->nullable(false)
		;
		$fields[] = NovaBelongsToDepend::make(__("Question"), "question",Question::class)
			->options(Question::relatableQuery($request,\App\Models\Question::query())->get())
			->withMeta(['titleKey' => 'text'])
			->nullable(false)
			->creationRules("required")
			->updateRules("required")
			->dependsOn('questionable')
		;
		$fields[] = NovaBelongsToDepend::make(__("Answer"), "answer")
			->optionsResolve(function ($question) {
				/** @var $question \App\Models\Question */
				// Reduce the amount of unnecessary data sent
				return $question->answers()->get(['id','text']);
			})
			->withMeta(['titleKey' => 'text'])
			->dependsOn('question')
			->nullable(false)
			->creationRules("required")
			->updateRules("required");

        return $fields;
    }

with the Question::relatableQuery method:


public static function relatableQuery(NovaRequest $request, $query)
	{
		$resource = $request->route('resource');
		if ($resource === "answered-questions") {
			$morphtype = $request->request->get("type");
			if ($morphtype === "patients") {
				$query = $query->where("type","=",\App\Models\Question::TYPE_PATIENT);
			}
			else if ($morphtype === "caregivers") {
				$query = $query->where("type","=",\App\Models\Question::TYPE_CAREGIVER);
			}
			else {
				$query = $query->where("id","=","-1");
			}
		}
		return $query;
	}

Question::relatableQuery is called multiple times so initially query returns no results, after user select Patient or Caregiver from the Morph field, relatableQuery returns many items.

Problem is NovaBelongsToDepend question field does not reflect that options are changed in the view.

Any ideas ?

Thank you.

PS: it seems that dependsTo method works only if relation represents another NovaBelongsToDepend field.

giancanuz avatar Nov 13 '19 11:11 giancanuz