@@ -248,6 +248,20 @@ public function isNullable(): bool
248248 return $ this ->nullable ;
249249 }
250250
251+ /**
252+ * Set the filterable attribute.
253+ */
254+ public function filterable (bool |Closure $ value = true , ?Closure $ callback = null ): static
255+ {
256+ $ callback ??= function (Request $ request , Builder $ query , mixed $ value ): Builder {
257+ return $ query ->whereHas ($ this ->getModelAttribute (), static function (Builder $ query ) use ($ value ): Builder {
258+ return $ query ->whereKey ($ value );
259+ });
260+ };
261+
262+ return parent ::filterable ($ value , $ callback );
263+ }
264+
251265 /**
252266 * {@inheritdoc}
253267 */
@@ -1036,4 +1050,41 @@ public function toEdit(Request $request, Model $model, Model $related): array
10361050 ),
10371051 ]);
10381052 }
1053+
1054+ /**
1055+ * Get the filter representation of the field.
1056+ */
1057+ public function toFilter (): Filter
1058+ {
1059+ return new class ($ this ) extends RenderableFilter
1060+ {
1061+ protected Relation $ field ;
1062+
1063+ public function __construct (Relation $ field )
1064+ {
1065+ parent ::__construct ($ field ->getModelAttribute ());
1066+
1067+ $ this ->field = $ field ;
1068+ }
1069+
1070+ public function apply (Request $ request , Builder $ query , mixed $ value ): Builder
1071+ {
1072+ return $ this ->field ->resolveFilterQuery ($ request , $ query , $ value );
1073+ }
1074+
1075+ public function toField (): Field
1076+ {
1077+ return Select::make ($ this ->field ->getLabel (), $ this ->getRequestKey ())
1078+ ->value (fn (Request $ request ): mixed => $ this ->getValue ($ request ))
1079+ ->nullable ()
1080+ ->options (function (Request $ request , Model $ model ): array {
1081+ return array_column (
1082+ $ this ->field ->resolveOptions ($ request , $ model ),
1083+ 'label ' ,
1084+ 'value ' ,
1085+ );
1086+ });
1087+ }
1088+ };
1089+ }
10391090}
0 commit comments