morphMany( CustomFieldValue::class, 'custom_field_valuable', ); } /** * Drop the answers when the record that owns them goes. * * The existence check spares the delete statement when there is nothing * to remove, at the price of a query that asks first. */ protected static function booted() { static::deleting(function ($record) { if ($record->fields()->exists()) { $record->fields()->delete(); } }); } /** * The answer this record holds for the field with the given slug, with * the definition already loaded alongside it. * * Null when this record never answered that field -- and equally when no * field carries the slug at all. */ public function getCustomFieldBySlug($slug) { return $this->fields() ->with('customField') ->whereHas('customField', fn ($definition) => $definition->where('slug', $slug)) ->first(); } /** * The answer itself, read from the column its type maps to. This is what * a document placeholder naming the slug resolves to. */ public function getCustomFieldValueBySlug($slug) { return $this->getCustomFieldBySlug($slug)?->defaultAnswer; } }